From aeb8fad73dac588d62e933b75afe04501cb70fe8 Mon Sep 17 00:00:00 2001 From: mingeung Date: Tue, 25 Nov 2025 11:44:07 +0900 Subject: [PATCH 01/61] =?UTF-8?q?=E2=9C=A8=20Feat:=20quizRoomServiceImpl?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codeBoy_backend/pom.xml | 1 + .../mvc/controller/MemberController.java | 12 +++--- .../com/codeboy/mvc/model/dao/CommentDao.java | 2 +- .../mvc/model/dao/IncorrectNoteDao.java | 2 +- .../com/codeboy/mvc/model/dao/MemberDao.java | 12 +++--- .../com/codeboy/mvc/model/dao/ProblemDao.java | 2 +- .../codeboy/mvc/model/dao/QuizRoomDao.java | 18 ++++----- .../com/codeboy/mvc/model/dao/ScoreDao.java | 12 +++--- .../mvc/model/dao/UserIncorrectNoteDao.java | 3 +- .../codeboy/mvc/model/dao/UserProblemDao.java | 9 ++--- .../com/codeboy/mvc/model/dto/Member.java | 2 + .../com/codeboy/mvc/model/dto/Problem.java | 2 +- .../com/codeboy/mvc/model/dto/UserScore.java | 2 +- .../mvc/model/service/MemberService.java | 5 +-- .../mvc/model/service/QuizRoomService.java | 13 +++---- .../model/service/QuizRoomServiceImpl.java | 39 +++++++++++++++++++ 16 files changed, 87 insertions(+), 49 deletions(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java diff --git a/codeBoy_backend/pom.xml b/codeBoy_backend/pom.xml index aa498cf..ec0e097 100644 --- a/codeBoy_backend/pom.xml +++ b/codeBoy_backend/pom.xml @@ -30,6 +30,7 @@ 17 + org.springframework.boot spring-boot-starter-web diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java index 0a18715..a8f6136 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java @@ -13,20 +13,20 @@ @RequestMapping("/api-member") @Tag(name="Member RESTful API", description = "Member CRUD를 할 수 있는 REST API") public class MemberController { - + // @Autowired // private MemberService memberService; - - + + @PostMapping("/signup") public String signup(@ModelAttribute Member member){ return "회원가입 성공?"; } @GetMapping(){ - + } - - + + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java index df05e7e..28f652a 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java @@ -6,7 +6,7 @@ public interface CommentDao { public List selectAllByProblemId(long problemId); - + public void insertComment(Comment comment); public void updateComment(Comment comment); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java index 5a617b2..929c13c 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java @@ -11,7 +11,7 @@ public interface IncorrectNoteDao { //유저가 자신의 오답노트 안에서 문제를 삭제 public void deleteIncorrectProblem(long memberId, long problemId); - + //오답노트에 문제 추가 public void insertIncorrectProblem(long memberId, long problemId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java index 6615b7c..2b45cfe 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java @@ -5,14 +5,14 @@ public interface MemberDao { public void insertMember(Member member); - + public Member selectMember(String id, String password); - - //멤버 삭제 -> db에서는 status 변경 + + //멤버 삭제 -> db에서는 status 변경 public void delete(int memberId); - + //멤버 업데이트 -> db에서는 patch(nickname, email, id) public void updateMember(long memberId, MemberUpdateRequest memberUpdateRequest); - - + + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ProblemDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ProblemDao.java index d98bc01..04d938e 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ProblemDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ProblemDao.java @@ -8,5 +8,5 @@ public interface ProblemDao { //문제 조회 public List selectProblem(Category category); - + } \ No newline at end of file diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java index 67a7ce4..db837f9 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java @@ -6,26 +6,26 @@ import com.codeboy.mvc.model.dto.QuizRoomMember; public interface QuizRoomDao { - + //quiz_room 테이블. 퀴즈룸 생성. 생성된 퀴즈룸 id 반환 public int insertQuizRoom(); - + //quiz_room_member 테이블에 값 넣기 (퀴즈방 입장) - 참가자/호스트 public void insertMemberToQuizRoom(QuizRoomMember quizRoomMember); - + //모든 퀴즈룸 조회하기 public List selectAllQuizRoom(); - - + + //하나의 퀴즈룸 조회(참가 멤버확인) public List selectOneQuizRoom(int roomId); - + //퀴즈룸 수정 - - + + //퀴즈룸 삭제 - public void deleteQuizRoom(long roomId); + public boolean deleteQuizRoom(long roomId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ScoreDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ScoreDao.java index 40a981a..8245fd0 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ScoreDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ScoreDao.java @@ -7,15 +7,15 @@ public interface ScoreDao { //스코어 등록 public void insertScore(UserScore userScore); - - //모든 스코어 조회 + + //모든 스코어 조회 public List selectAllUserScore(); - + //한 멤버의 스코어 조회 public int selectOneUserScore(int memberId); - + //멤버 스코어 업데이트 public void updateUserScore(UserScore userScore); - - + + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.java index 537c5e1..b996c4b 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.java @@ -2,7 +2,6 @@ import java.util.List; -import com.codeboy.mvc.model.dto.Problem; import com.codeboy.mvc.model.dto.UserProblem; public interface UserIncorrectNoteDao { @@ -12,7 +11,7 @@ public interface UserIncorrectNoteDao { //유저가 자신의 오답노트 안에서 문제를 삭제 public void deleteUserIncorrectProblem(long memberId, long userProblemId); - + //(중간자 테이블)오답노트에 문제 추가 public void insertUserIncorrectProblem(long memberId, long userProblemId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemDao.java index b2ad1ff..9730bef 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemDao.java @@ -3,22 +3,21 @@ import java.util.List; import com.codeboy.common.Category; -import com.codeboy.mvc.model.dto.Problem; import com.codeboy.mvc.model.dto.UserProblem; public interface UserProblemDao extends ProblemDao{ - + //문제세트 조회 public List selectUserProblem(Category category); //문제 생성하기 public void insertUserProblem(UserProblem userProblem); - + //문제 세트 만들기 public void insertUserProblemSet(List userProblemList); - + //문제 수정 public void updateUserProblem(UserProblem userProblem); - + //문제 삭제 public int deleteUserProblem(int id); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java index f657755..a3c174a 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java @@ -1,7 +1,9 @@ package com.codeboy.mvc.model.dto; import java.sql.Timestamp; + import com.codeboy.common.Status; + import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Problem.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Problem.java index e93caa9..195d199 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Problem.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Problem.java @@ -22,5 +22,5 @@ public class Problem { private String choice4; private String answer; private Category category; - + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserScore.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserScore.java index e65a711..03c3747 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserScore.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserScore.java @@ -15,6 +15,6 @@ public class UserScore { private long memberId; private int score; - + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java index 90316ff..7a890e3 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java @@ -2,7 +2,6 @@ import com.codeboy.mvc.model.dto.Member; import com.codeboy.mvc.model.dto.MemberUpdateRequest; -import com.codeboy.mvc.model.dto.MemberUpdateRequest; public interface MemberService { //회원가입 @@ -11,9 +10,9 @@ public interface MemberService { //회원 정보 가져오기기 public Member readMember(String id, String password); - //회원 탈퇴 + //회원 탈퇴 public void withdrawal(int memberId); - + //회원정보 수정-> db에서는 patch(nickname, email, id) public void updateMember(long memberId, MemberUpdateRequest memberUpdateRequest); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java index cd3f65e..5544856 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java @@ -3,21 +3,20 @@ import java.util.List; import com.codeboy.mvc.model.dto.QuizRoom; +import com.codeboy.mvc.model.dto.QuizRoomMember; public interface QuizRoomService { //퀴즈방 전체 조회 public List getQuizRoomList(); - + //퀴즈 방 만들기 -> 생성된 퀴즈방 id를 return //퀴즈방 생성하고 생성된 퀴즈방에 방장 id 넣기 public int createQuizRoom(long memberId); - + //참가자 채팅방 입장 - public void joinQuizRoom(long memberId, long quizRoomId); - + public void joinQuizRoom(QuizRoomMember quizRoomMember); + //퀴즈룸 삭제 - public boolean deleteQuizRoom() - - + public boolean deleteQuizRoom(long roomId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java new file mode 100644 index 0000000..b864f1a --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java @@ -0,0 +1,39 @@ +package com.codeboy.mvc.model.service; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.codeboy.mvc.model.dao.QuizRoomDao; +import com.codeboy.mvc.model.dto.QuizRoom; +import com.codeboy.mvc.model.dto.QuizRoomMember; + +public class QuizRoomServiceImpl implements QuizRoomService{ + @Autowired + private QuizRoomDao quizRoomDao; + + + @Override + public List getQuizRoomList() { + return quizRoomDao.selectAllQuizRoom(); + } + + @Override + public int createQuizRoom(long memberId) { + return quizRoomDao.insertQuizRoom(); + } + + @Override + public void joinQuizRoom(QuizRoomMember quizRoomMember) { + quizRoomDao.insertMemberToQuizRoom(quizRoomMember); + return; + + } + + @Override + public boolean deleteQuizRoom(long roomId) { + boolean ok = quizRoomDao.deleteQuizRoom(roomId); + return ok; + } + +} From af5d30ccbb05a7b8d83d37c75cc24b5e297f10ca Mon Sep 17 00:00:00 2001 From: junhyung8795 Date: Tue, 25 Nov 2025 13:57:44 +0900 Subject: [PATCH 02/61] =?UTF-8?q?=E2=9C=A8=20CommentService=20getAllCommen?= =?UTF-8?q?tsById=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codeBoy_backend/.gitignore | 1 + .../codeboy/mvc/model/service/CommentService.java | 5 ++++- .../mvc/model/service/CommentServiceImpl.java | 12 ++++++++++++ .../src/main/resources/mappers/CommentMapper.xml | 10 ++++++++++ 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java create mode 100644 codeBoy_backend/src/main/resources/mappers/CommentMapper.xml diff --git a/codeBoy_backend/.gitignore b/codeBoy_backend/.gitignore index 667aaef..c5d3e1f 100644 --- a/codeBoy_backend/.gitignore +++ b/codeBoy_backend/.gitignore @@ -31,3 +31,4 @@ build/ ### VS Code ### .vscode/ +/.metadata/ diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java index 962d5ec..197708c 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java @@ -1,5 +1,8 @@ package com.codeboy.mvc.model.service; -public class CommentService { +public interface CommentService { + //유저제작 문제 세트Id로 조회 + public List getAllCommentsById(int userProblemSetId); + // } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java new file mode 100644 index 0000000..e340390 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java @@ -0,0 +1,12 @@ +package com.codeboy.mvc.model.service; + +import com.codeboy.mvc.model.dto.Comment; + +public class CommentServiceImpl implements CommentService { + @Override + public List getAllCommentsById(int userProblemSetId) { + return null; + } + //유저제작 문제 세트Id로 조회 + +} diff --git a/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml b/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml new file mode 100644 index 0000000..b403191 --- /dev/null +++ b/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file From d3f78f49cbd9f42b90e19b1a7aedc926e7dbfad3 Mon Sep 17 00:00:00 2001 From: junhyung8795 Date: Wed, 26 Nov 2025 02:33:42 +0900 Subject: [PATCH 03/61] =?UTF-8?q?=E2=9C=A8Comment=20Dao,=20Controller,=20S?= =?UTF-8?q?ervice,=20ServiceImpl,=20CommentMapper.xml=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 개발 도중 Comment는 UserProblemSet과 연관이 깊어서 차후 개발 영역을 서로 재분배해야할 필요성이 있음. 2. 테스트를 위해서 MyBatisConfig를 추가하고 MapperScan 적 3. ProblemMapper, QuizRoomMapper, ScoreMapper수정 4. UserMapper를 삭제하고 MemeberMapper를 추 --- .../com/codeboy/mvc/config/MyBatisConfig.java | 10 +++ .../mvc/controller/CommentController.java | 80 +++++++++++++++++++ .../mvc/controller/MemberController.java | 10 +-- .../com/codeboy/mvc/model/dao/CommentDao.java | 18 +++-- .../mvc/model/service/CommentService.java | 17 +++- .../mvc/model/service/CommentServiceImpl.java | 52 ++++++++++-- .../src/main/resources/application.properties | 6 +- .../main/resources/mappers/CommentMapper.xml | 32 ++++++-- .../main/resources/mappers/MemberMapper.xml | 10 +++ .../main/resources/mappers/ProblemMapper.xml | 10 ++- .../main/resources/mappers/QuizRoomMapper.xml | 6 +- .../main/resources/mappers/ScoreMapper.xml | 10 ++- .../src/main/resources/mappers/UserMapper.xml | 1 - 13 files changed, 228 insertions(+), 34 deletions(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/config/MyBatisConfig.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java create mode 100644 codeBoy_backend/src/main/resources/mappers/MemberMapper.xml delete mode 100644 codeBoy_backend/src/main/resources/mappers/UserMapper.xml diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/config/MyBatisConfig.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/config/MyBatisConfig.java new file mode 100644 index 0000000..f657d4d --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/config/MyBatisConfig.java @@ -0,0 +1,10 @@ +package com.codeboy.mvc.config; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@MapperScan("com.codeboy.mvc.model.dao") +public class MyBatisConfig { + +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java new file mode 100644 index 0000000..6c10b42 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java @@ -0,0 +1,80 @@ +package com.codeboy.mvc.controller; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatusCode; +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.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.codeboy.mvc.model.dto.Comment; +import com.codeboy.mvc.model.service.CommentService; + +@RestController +@RequestMapping("/api/user-problem-sets") +public class CommentController { + private final CommentService commentService; + + @Autowired + public CommentController(CommentService commentService) { + this.commentService = commentService; + } + + + @GetMapping("{userProblemSetId}/comments") + public ResponseEntity> getAllCommentsById(@PathVariable("userProblemSetId") long userProblemSetId){ + List comments = commentService.getAllCommentsById(userProblemSetId); + if(comments.size() > 0) { + //성공적으로 댓글들을 조회한 경우 + return new ResponseEntity>(comments, HttpStatusCode.valueOf(200)); + } + //댓글 조회에 실패한 경우 + return new ResponseEntity>(HttpStatusCode.valueOf(404)); + + } + + @PostMapping("{userProblemSetId}/comments") + public ResponseEntity addComment(@PathVariable("userProblemSetId") long userProblemSetId, @RequestBody Comment comment){ + int result = commentService.addComment(userProblemSetId, comment); + if(result == 1) { + //sql의 반환값이 1개면 댓글 추가에 성공한 경우 + return new ResponseEntity("댓글 추가 성공", HttpStatusCode.valueOf(200)); + } + //서버 오류로 댓글 추가에 실패한 경우 + return new ResponseEntity("댓글 추가 실패", HttpStatusCode.valueOf(500)); + + } + + @PutMapping("{userProblemSetId}/comments") + public ResponseEntity updateComment(@PathVariable("commentId") long commentId, @RequestBody Comment comment){ + int result = commentService.updateComment(commentId, comment); + if(result == 1) { + //sql의 반환값이 1개면 댓글 업데이트에 성공 + return new ResponseEntity("댓글 수정 성공", HttpStatusCode.valueOf(200)); + } + //댓글 아이디가 존재하지 않을 경우, 업데이트 실패 + return new ResponseEntity("존재 하지 않는 댓글입니다.", HttpStatusCode.valueOf(404)); + + } + + @DeleteMapping("{userProblemSetId}/comments") + public ResponseEntity deleteComment(@PathVariable("commentId") long commentId){ + int result = commentService.deleteComment(commentId); + if(result == 1) { + //sql의 반환값이 1개면 댓글 삭제에 성공 + return new ResponseEntity("댓글 삭제 성공", HttpStatusCode.valueOf(200)); + } + //댓글 아이디가 존재하지 않을 경우, 삭제에 실패 + return new ResponseEntity("존재 하지 않는 댓글입니다.", HttpStatusCode.valueOf(404)); + + } + +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java index 0a18715..1480bfa 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java @@ -22,11 +22,11 @@ public class MemberController { public String signup(@ModelAttribute Member member){ return "회원가입 성공?"; } - - @GetMapping(){ - - } - +// +// @GetMapping(){ +// +// } +// } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java index df05e7e..d4fe707 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java @@ -2,14 +2,20 @@ import java.util.List; +import org.apache.ibatis.annotations.Mapper; + import com.codeboy.mvc.model.dto.Comment; +@Mapper public interface CommentDao { - public List selectAllByProblemId(long problemId); + public List selectCommentsByuserProblemSetId(long userProblemSetId); - public void insertComment(Comment comment); - - public void updateComment(Comment comment); - - public void deleteComment(long commentId); + //유저문제세트 id에다가 댓글을 달아야하므로 long userProblemSetId으로 지정 + public int insertComment(long userProblemSetId, Comment comment); + + //조회된 댓글의 id를 가져와서 수정하고 삭제함. + public int updateComment(long commentId, Comment comment); + + //조회된 댓글의 id를 가져와서 수정하고 삭제함. + public int deleteComment(long commentId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java index 197708c..779b154 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java @@ -1,8 +1,19 @@ package com.codeboy.mvc.model.service; +import java.util.List; + +import com.codeboy.mvc.model.dto.Comment; + public interface CommentService { //유저제작 문제 세트Id로 조회 - public List getAllCommentsById(int userProblemSetId); - - // + public List getAllCommentsById(long userProblemSetId); + + //유저제작 문제 세트Id로 조회후 해당 세트에 댓글 작성 + public int addComment(long userProblemSetId, Comment comment); +// + public int updateComment(long commentId, Comment comment); +// + public int deleteComment(long commentId); + + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java index e340390..49bbefe 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java @@ -1,12 +1,54 @@ package com.codeboy.mvc.model.service; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.codeboy.mvc.model.dao.CommentDao; import com.codeboy.mvc.model.dto.Comment; +@Service public class CommentServiceImpl implements CommentService { - @Override - public List getAllCommentsById(int userProblemSetId) { - return null; - } - //유저제작 문제 세트Id로 조회 + private final CommentDao commentDao; + + @Autowired + public CommentServiceImpl(CommentDao commentDao) { + this.commentDao = commentDao; + } + + + + // 유저제작 문제 세트Id로 조회 + @Override + public List getAllCommentsById(long userProblemSetId) { + return commentDao.selectCommentsByuserProblemSetId(userProblemSetId); + } + + @Override + public int addComment(long userProblemSetId, Comment comment ) { + return commentDao.insertComment(userProblemSetId, comment); + } + + + + @Override + public int updateComment(long commentId, Comment comment) { + return commentDao.updateComment(commentId, comment); + + } + + + + @Override + public int deleteComment(long commentId) { + return commentDao.deleteComment(commentId); + + } + + + + + } diff --git a/codeBoy_backend/src/main/resources/application.properties b/codeBoy_backend/src/main/resources/application.properties index 603f194..2ddba00 100644 --- a/codeBoy_backend/src/main/resources/application.properties +++ b/codeBoy_backend/src/main/resources/application.properties @@ -9,9 +9,9 @@ spring.application.name=codeBoy_backend # # spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -spring.datasource.url=jdbc:mysql://localhost:3306/ssafy_board?serverTimezone=UTC -spring.datasource.username=ssafy -spring.datasource.password=ssafy +spring.datasource.url=jdbc:mysql://localhost:3306/board_test?serverTimezone=UTC +spring.datasource.username=root +spring.datasource.password=HardRain77 #mybatis #mapper diff --git a/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml b/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml index b403191..1958626 100644 --- a/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml @@ -1,10 +1,30 @@ - + - + + + + + INSERT INTO comment (member_id, content, comment_date, user_problem_set) + VALUES (#{member_id}, #{content}, #{comment_date, #{user_problem_set}) + + + + UPDATE comment + SET content = #{content} + WHERE comment_id = #{commentId} + + + + DELETE + FROM comment + WHERE comment_id = #{commentId} + - - \ No newline at end of file + diff --git a/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml new file mode 100644 index 0000000..4a95a96 --- /dev/null +++ b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml b/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml index b994f53..666e8c0 100644 --- a/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml @@ -1 +1,9 @@ - \ No newline at end of file + + + + + + + + diff --git a/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml b/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml index d5660c4..17ce788 100644 --- a/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml @@ -3,7 +3,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + INSERT INTO quiz_room_member(member_id, room_id, is_host) - VALUES(#{memberId, roomId, isHost}); + VALUES(#{memberId}, #{roomId}, #{isHost}); @@ -48,4 +48,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/codeBoy_backend/src/main/resources/mappers/ScoreMapper.xml b/codeBoy_backend/src/main/resources/mappers/ScoreMapper.xml index b994f53..a6130f5 100644 --- a/codeBoy_backend/src/main/resources/mappers/ScoreMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/ScoreMapper.xml @@ -1 +1,9 @@ - \ No newline at end of file + + + + + + + + diff --git a/codeBoy_backend/src/main/resources/mappers/UserMapper.xml b/codeBoy_backend/src/main/resources/mappers/UserMapper.xml deleted file mode 100644 index b994f53..0000000 --- a/codeBoy_backend/src/main/resources/mappers/UserMapper.xml +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From a2b7c34f311c5da4963d5ac204c35480e9628263 Mon Sep 17 00:00:00 2001 From: junhyung8795 Date: Wed, 26 Nov 2025 03:47:26 +0900 Subject: [PATCH 04/61] =?UTF-8?q?=E2=9C=A8Member=20DAO,=20DTO,=20Service,?= =?UTF-8?q?=20ServiceImpl,=20Controller,=20MemberMapper=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.로그인과 로그아웃기능은 아직 구현 X + ID와 더불어 이메일도 중복불허용 제약을 걸어야할 것 같음. 2. DB에 memberId가 아닌 그냥 사람이 로그인할 때 사용하는 id가 "ID"로대문자로 저장돼있음. 이거 id로 고치는건 어떨지 의논해야함. 3. LoginRequest와 MemberUpdateRequest라는 DTO를 추가로 만들어 로그인할 때 id, password 수정할 때는 닉네임과 이메일은 바꿀 수 있다고 가정하고 구현. 4.deleteQuizRoom은 오류때문에 잠시 주석처리 5. Mapper.xml에서 공통적으로 mapper태그나 DML관련 태그들에서 오류가 뜸. 수정 필요. --- .../mvc/controller/MemberController.java | 170 +++++++++++++++--- .../com/codeboy/mvc/model/dao/MemberDao.java | 21 +-- .../codeboy/mvc/model/dto/LoginRequest.java | 20 +++ .../com/codeboy/mvc/model/dto/Member.java | 52 +++++- .../mvc/model/dto/MemberUpdateRequest.java | 19 ++ .../mvc/model/service/MemberService.java | 21 ++- .../mvc/model/service/MemberServiceImpl.java | 48 +++++ .../mvc/model/service/QuizRoomService.java | 2 +- .../main/resources/mappers/CommentMapper.xml | 44 ++--- .../main/resources/mappers/MemberMapper.xml | 41 ++++- 10 files changed, 364 insertions(+), 74 deletions(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/LoginRequest.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java index 1480bfa..23f2ff8 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java @@ -1,32 +1,156 @@ package com.codeboy.mvc.controller; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; -import com.codeboy.mvc.model.dto.Member; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; -import io.swagger.v3.oas.annotations.tags.Tag; +import com.codeboy.mvc.model.dto.Member; +import com.codeboy.mvc.model.dto.LoginRequest; +import com.codeboy.mvc.model.dto.MemberUpdateRequest; +import com.codeboy.mvc.model.service.MemberService; @RestController -@RequestMapping("/api-member") -@Tag(name="Member RESTful API", description = "Member CRUD를 할 수 있는 REST API") +@RequestMapping("/api") public class MemberController { - -// @Autowired -// private MemberService memberService; - - - @PostMapping("/signup") - public String signup(@ModelAttribute Member member){ - return "회원가입 성공?"; - } -// -// @GetMapping(){ -// -// } -// - + private final MemberService memberService; + + @Autowired + public MemberController(MemberService memberService) { + this.memberService = memberService; + } + + /** + * 회원가입 + * POST /api/members + * RequestBody: { id, password, nickname, email } + * Response: + * 201 생성 성공 + * 400 잘못된 요청 + * 409 아이디/이메일 중복 + */ + @PostMapping("/members") + public ResponseEntity signUp(@RequestBody Member member) { + // TODO: 아이디/이메일 중복 체크 로직은 나중에 추가 + int result = memberService.signUp(member); + + if (result == 1) { + // Location 헤더에 새로 생성된 리소스 URI 넣어줄 수도 있음 + URI location = URI.create("/api/members/" + member.getMemberId()); + return ResponseEntity + .status(HttpStatusCode.valueOf(201)) + .location(location) + .body("회원가입 성공"); + } else { + return ResponseEntity + .status(HttpStatusCode.valueOf(400)) + .body("회원가입 실패"); + } + //아이디/이메일 중복로직은 나중에 구 + } + + /** + * 로그인 + * POST /api/auth/login + * RequestBody: { id, password } + * Response: + * 200 성공 시 { token, memberId, nickname } + * 401 실패 시 { error: "로그인 실패" } + */ + @PostMapping("/auth/login") + public ResponseEntity login(@RequestBody LoginRequest request) { + return null; + } + + /** + * 로그아웃 + * POST /api/auth/logout + * RequestBody: 없음 + * Response: + * 204 성공 시 본문 없음 + */ + @PostMapping("/auth/logout") + public ResponseEntity logout() { + return null; + } + + /** + * 내 정보 수정 + * PUT /api/members/me + * RequestBody: { nickname?, email?, password? } + * Response: + * 200 성공 시 수정된 정보 or 메시지 + * 400 잘못된 요청 + * 401 인증 실패 + */ + @PutMapping("/members/{memberId}") + public ResponseEntity updateMe(@RequestBody MemberUpdateRequest request, @PathVariable long memberId ) { + //파라미터로 memberId받아서 해당회원의 정보를 수정 + + Member member = memberService.getMemberByMemberId(memberId); + //회원을 못찾는 경우 ->존재하지 않는 memberId인경우 + if (member == null) { + return ResponseEntity + .status(HttpStatusCode.valueOf(401)) + .body("인증된 회원을 찾을 수 없습니다."); + } + + //닉네임과 이메일은 바꿀 수 있다고 가정. 필요하면 ID도..? + if (request.getNickName() != null) { + member.setNickname(request.getNickName()); + } + if (request.getEmail() != null) { + member.setEmail(request.getEmail()); + } + + + int result = memberService.updateMember(memberId, member); + + if (result == 1) { + return ResponseEntity + .status(HttpStatusCode.valueOf(200)) + .body(member); // 또는 "수정 성공" 메시지 + } else { + return ResponseEntity + .status(HttpStatusCode.valueOf(400)) + .body("회원정보 수정 실패"); + } + } + + /** + * 회원 탈퇴 (비활성화) + * DELETE /api/members/me + * Response: + * 204 성공 시 본문 없음 + * 401 인증 실패 + */ + @DeleteMapping("/members/me") + public ResponseEntity deleteMe() { + // TODO: 실제 구현에서는 JWT/세션에서 memberId를 가져와야 함. + long currentMemberId = 1L; + + Member member = memberService.getMemberByMemberId(currentMemberId); + if (member == null) { + return ResponseEntity + .status(HttpStatusCode.valueOf(401)) + .body("인증된 회원을 찾을 수 없습니다."); + } + + int result = memberService.deactivateMember(currentMemberId); + + if (result == 1) { + return ResponseEntity + .status(HttpStatusCode.valueOf(204)) + .build(); + } else { + return ResponseEntity + .status(HttpStatusCode.valueOf(400)) + .body("회원 탈퇴 처리 실패"); + } + } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java index 6615b7c..566e594 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java @@ -4,15 +4,16 @@ import com.codeboy.mvc.model.dto.MemberUpdateRequest; public interface MemberDao { - public void insertMember(Member member); - - public Member selectMember(String id, String password); - - //멤버 삭제 -> db에서는 status 변경 - public void delete(int memberId); - - //멤버 업데이트 -> db에서는 patch(nickname, email, id) - public void updateMember(long memberId, MemberUpdateRequest memberUpdateRequest); - + // 회원 가입 + int insertMember(Member member); + + // PK로 조회 + Member selectMemberByMemberId(long memberId); + + // 닉네임/이메일/비밀번호 수정 + int updateMember(long memberId, Member member); + + // 회원 비활성화(탈퇴) - status, isDeleted 업데이트 + int deleteMember(long memberId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/LoginRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/LoginRequest.java new file mode 100644 index 0000000..eb40fe4 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/LoginRequest.java @@ -0,0 +1,20 @@ +package com.codeboy.mvc.model.dto; + +public class LoginRequest { + //로그인을 할 때에는 id와 password만 사용하니 이를 간편하게 전달하기 위한 DTO + private String id; + private String password; + + public LoginRequest() {} + + public LoginRequest(String id, String password) { + this.id = id; + this.password = password; + } + + public String getId() { return id; } + public void setId(String id) { this.id = id; } + + public String getPassword() { return password; } + public void setPassword(String password) { this.password = password; } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java index f657755..af57b02 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java @@ -10,8 +10,7 @@ @NoArgsConstructor @AllArgsConstructor -@Getter -@Setter + @Schema(description="회원 DTO") public class Member { private long memberId; @@ -22,5 +21,54 @@ public class Member { private Timestamp signupDate; private Status status; private Timestamp deletedDate; + public long getMemberId() { + return memberId; + } + public void setMemberId(long memberId) { + this.memberId = memberId; + } + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + public String getNickname() { + return nickname; + } + public void setNickname(String nickname) { + this.nickname = nickname; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + public Timestamp getSignupDate() { + return signupDate; + } + public void setSignupDate(Timestamp signupDate) { + this.signupDate = signupDate; + } + public Status getStatus() { + return status; + } + public void setStatus(Status status) { + this.status = status; + } + public Timestamp getDeletedDate() { + return deletedDate; + } + public void setDeletedDate(Timestamp deletedDate) { + this.deletedDate = deletedDate; + } + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/MemberUpdateRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/MemberUpdateRequest.java index eb94e12..a05de46 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/MemberUpdateRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/MemberUpdateRequest.java @@ -15,4 +15,23 @@ public class MemberUpdateRequest { private String nickName; private String id; private String email; + public String getNickName() { + return nickName; + } + public void setNickName(String nickName) { + this.nickName = nickName; + } + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java index 90316ff..7a184c3 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java @@ -1,19 +1,18 @@ package com.codeboy.mvc.model.service; import com.codeboy.mvc.model.dto.Member; -import com.codeboy.mvc.model.dto.MemberUpdateRequest; -import com.codeboy.mvc.model.dto.MemberUpdateRequest; public interface MemberService { - //회원가입 - public void signupMember(); - //회원 정보 가져오기기 - public Member readMember(String id, String password); + // 회원 가입 + int signUp(Member member); - //회원 탈퇴 - public void withdrawal(int memberId); - - //회원정보 수정-> db에서는 patch(nickname, email, id) - public void updateMember(long memberId, MemberUpdateRequest memberUpdateRequest); + // PK로 회원 조회 (마이페이지 같은 용도) + Member getMemberByMemberId(long memberId); + + // 내 정보 수정 + int updateMember(long memberId, Member member); + + // 회원 비활성화(탈퇴) + int deactivateMember(long memberId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java new file mode 100644 index 0000000..a003e65 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java @@ -0,0 +1,48 @@ +package com.codeboy.mvc.model.service; + +import java.sql.Timestamp; +import java.time.LocalDateTime; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.codeboy.mvc.model.dao.MemberDao; +import com.codeboy.mvc.model.dto.Member; +import com.codeboy.common.Status; + +@Service +public class MemberServiceImpl implements MemberService { + + private final MemberDao memberDao; + + @Autowired + public MemberServiceImpl(MemberDao memberDao) { + this.memberDao = memberDao; + } + + @Override + public int signUp(Member member) { + // 기본값 세팅 + member.setStatus(Status.ACTIVE); + member.setDeletedDate(null); + member.setSignupDate(Timestamp.valueOf(LocalDateTime.now())); + return memberDao.insertMember(member); + } + + @Override + public Member getMemberByMemberId(long memberId) { + return memberDao.selectMemberByMemberId(memberId); + } + + + @Override + public int updateMember(long memberId, Member member) { + + return memberDao.updateMember(memberId, member); + } + + @Override + public int deactivateMember(long memberId) { + return memberDao.deleteMember(memberId); + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java index cd3f65e..a9d0647 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java @@ -17,7 +17,7 @@ public interface QuizRoomService { public void joinQuizRoom(long memberId, long quizRoomId); //퀴즈룸 삭제 - public boolean deleteQuizRoom() +// public boolean deleteQuizRoom() } diff --git a/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml b/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml index 1958626..29e730f 100644 --- a/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml @@ -4,27 +4,27 @@ - - - - INSERT INTO comment (member_id, content, comment_date, user_problem_set) - VALUES (#{member_id}, #{content}, #{comment_date, #{user_problem_set}) - - - - UPDATE comment - SET content = #{content} - WHERE comment_id = #{commentId} - - - - DELETE - FROM comment - WHERE comment_id = #{commentId} - + + + + INSERT INTO comment (member_id, content, comment_date, user_problem_set) + VALUES (#{member_id}, #{content}, #{comment_date, #{user_problem_set}) + + + + UPDATE comment + SET content = #{content} + WHERE comment_id = #{commentId} + + + + DELETE + FROM comment + WHERE comment_id = #{commentId} + diff --git a/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml index 4a95a96..f756b45 100644 --- a/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml @@ -1,10 +1,41 @@ - - + + - - + + + + INSERT INTO member (ID, password, nickname, email, signup_Date, deleted_date, status) + VALUES (#{id}, #{password}, #{nickname}, #{email}, + #{signupDate}, #{deletedDate}, #{status}) + + + + + + + UPDATE member + SET nickname = #{nickname}, + email = #{email}, + password = #{password}, + WHERE member_id = #{memberId} + + + + UPDATE member + SET status = 'INACTIVE', + deleted_date = #{deletedDate} + WHERE member_id = #{memberId} + From 79d96c061a1819cc6e895e9539df2d9c0f00075b Mon Sep 17 00:00:00 2001 From: mingeung Date: Wed, 26 Nov 2025 13:48:32 +0900 Subject: [PATCH 05/61] =?UTF-8?q?feat=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20API=20=EC=84=B1=EA=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .project | 23 ++++++++++++++++ codeBoy_backend/pom.xml | 11 ++++---- .../mvc/controller/MemberController.java | 16 +++++------ .../codeboy/mvc/model/dao/QuizRoomDao.java | 8 +++--- .../codeboy/mvc/model/dto/ApiResponse.java | 17 ++++++++++++ .../mvc/model/dto/CreateQuizRoomRequest.java | 13 +++++++++ .../com/codeboy/mvc/model/dto/QuizRoom.java | 2 ++ .../codeboy/mvc/model/dto/QuizRoomMember.java | 26 ++++++++++++++++++ .../mvc/model/service/QuizRoomService.java | 12 ++++++--- .../model/service/QuizRoomServiceImpl.java | 27 ++++++++++++++----- .../src/main/resources/application.properties | 2 +- .../main/resources/mappers/ProblemMapper.xml | 9 ++++++- .../main/resources/mappers/QuizRoomMapper.xml | 15 +++++------ .../main/resources/mappers/ScoreMapper.xml | 9 ++++++- .../src/main/resources/mappers/UserMapper.xml | 9 ++++++- 15 files changed, 161 insertions(+), 38 deletions(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/ApiResponse.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CreateQuizRoomRequest.java diff --git a/.project b/.project index e40ff58..cb29ace 100644 --- a/.project +++ b/.project @@ -5,7 +5,30 @@ + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.springframework.ide.eclipse.boot.validation.springbootbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature diff --git a/codeBoy_backend/pom.xml b/codeBoy_backend/pom.xml index ec0e097..e62266d 100644 --- a/codeBoy_backend/pom.xml +++ b/codeBoy_backend/pom.xml @@ -73,11 +73,12 @@ org.springframework.boot spring-boot-starter - - org.projectlombok - lombok - true - + + org.projectlombok + lombok + 1.18.42 + + diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java index a8f6136..132b18a 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java @@ -18,14 +18,14 @@ public class MemberController { // private MemberService memberService; - @PostMapping("/signup") - public String signup(@ModelAttribute Member member){ - return "회원가입 성공?"; - } - - @GetMapping(){ - - } +// @PostMapping("/signup") +// public String signup(@ModelAttribute Member member){ +// return "회원가입 성공?"; +// } +// +// @GetMapping(){ +// +// } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java index db837f9..20a2257 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java @@ -4,14 +4,16 @@ import com.codeboy.mvc.model.dto.QuizRoom; import com.codeboy.mvc.model.dto.QuizRoomMember; +import org.apache.ibatis.annotations.Mapper; +@Mapper public interface QuizRoomDao { //quiz_room 테이블. 퀴즈룸 생성. 생성된 퀴즈룸 id 반환 - public int insertQuizRoom(); + public int insertQuizRoom(QuizRoom room); //quiz_room_member 테이블에 값 넣기 (퀴즈방 입장) - 참가자/호스트 - public void insertMemberToQuizRoom(QuizRoomMember quizRoomMember); + public int insertMemberToQuizRoom(QuizRoomMember quizRoomMember); //모든 퀴즈룸 조회하기 @@ -20,7 +22,7 @@ public interface QuizRoomDao { //하나의 퀴즈룸 조회(참가 멤버확인) - public List selectOneQuizRoom(int roomId); + public List selectOneQuizRoom(long roomId); //퀴즈룸 수정 diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/ApiResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/ApiResponse.java new file mode 100644 index 0000000..ca89685 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/ApiResponse.java @@ -0,0 +1,17 @@ +package com.codeboy.mvc.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ApiResponse { + private boolean success; + private String message; + private T data; + + + // getter, setter 생략 +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CreateQuizRoomRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CreateQuizRoomRequest.java new file mode 100644 index 0000000..0c1d44d --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CreateQuizRoomRequest.java @@ -0,0 +1,13 @@ +package com.codeboy.mvc.model.dto; + +import lombok.*; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class CreateQuizRoomRequest { + private long memberId; + +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/QuizRoom.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/QuizRoom.java index 059c4aa..01ca516 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/QuizRoom.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/QuizRoom.java @@ -13,4 +13,6 @@ @Schema(description="퀴즈방 DTO") public class QuizRoom { private long roomId; + + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/QuizRoomMember.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/QuizRoomMember.java index d6cdd6e..6a0df26 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/QuizRoomMember.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/QuizRoomMember.java @@ -16,4 +16,30 @@ public class QuizRoomMember { private long memberId; private long roomId; private Boolean isHost; + public long getQuizRoomMemberId() { + return quizRoomMemberId; + } + public void setQuizRoomMemberId(long quizRoomMemberId) { + this.quizRoomMemberId = quizRoomMemberId; + } + public long getMemberId() { + return memberId; + } + public void setMemberId(long memberId) { + this.memberId = memberId; + } + public long getRoomId() { + return roomId; + } + public void setRoomId(long roomId) { + this.roomId = roomId; + } + public Boolean getIsHost() { + return isHost; + } + public void setIsHost(Boolean isHost) { + this.isHost = isHost; + } + + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java index 5544856..175a381 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java @@ -2,20 +2,24 @@ import java.util.List; +import com.codeboy.mvc.model.dto.Member; +import org.springframework.stereotype.Service; + import com.codeboy.mvc.model.dto.QuizRoom; import com.codeboy.mvc.model.dto.QuizRoomMember; - +@Service public interface QuizRoomService { //퀴즈방 전체 조회 public List getQuizRoomList(); //퀴즈 방 만들기 -> 생성된 퀴즈방 id를 return - //퀴즈방 생성하고 생성된 퀴즈방에 방장 id 넣기 - public int createQuizRoom(long memberId); + public int createQuizRoom(); + + public List getOneQuizRoomMember(long roomId); //참가자 채팅방 입장 - public void joinQuizRoom(QuizRoomMember quizRoomMember); + public boolean joinQuizRoom(QuizRoomMember quizRoomMember); //퀴즈룸 삭제 public boolean deleteQuizRoom(long roomId); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java index b864f1a..244e67d 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java @@ -2,12 +2,15 @@ import java.util.List; +import com.codeboy.mvc.model.dto.Member; import org.springframework.beans.factory.annotation.Autowired; import com.codeboy.mvc.model.dao.QuizRoomDao; import com.codeboy.mvc.model.dto.QuizRoom; import com.codeboy.mvc.model.dto.QuizRoomMember; +import org.springframework.stereotype.Service; +@Service public class QuizRoomServiceImpl implements QuizRoomService{ @Autowired private QuizRoomDao quizRoomDao; @@ -18,15 +21,27 @@ public List getQuizRoomList() { return quizRoomDao.selectAllQuizRoom(); } + @Override + public List getOneQuizRoomMember(long roomId) { + return quizRoomDao.selectOneQuizRoom( roomId); + + } + @Override - public int createQuizRoom(long memberId) { - return quizRoomDao.insertQuizRoom(); - } + public int createQuizRoom() { + QuizRoom room = new QuizRoom(); + return quizRoomDao.insertQuizRoom(room); + + } @Override - public void joinQuizRoom(QuizRoomMember quizRoomMember) { - quizRoomDao.insertMemberToQuizRoom(quizRoomMember); - return; + public boolean joinQuizRoom(QuizRoomMember quizRoomMember) { + int rowsAffected = quizRoomDao.insertMemberToQuizRoom(quizRoomMember); + if (rowsAffected > 0) { + return true; + } else { + return false; + } } diff --git a/codeBoy_backend/src/main/resources/application.properties b/codeBoy_backend/src/main/resources/application.properties index 603f194..b8c6c8d 100644 --- a/codeBoy_backend/src/main/resources/application.properties +++ b/codeBoy_backend/src/main/resources/application.properties @@ -9,7 +9,7 @@ spring.application.name=codeBoy_backend # # spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -spring.datasource.url=jdbc:mysql://localhost:3306/ssafy_board?serverTimezone=UTC +spring.datasource.url=jdbc:mysql://localhost:3306/board_test?serverTimezone=UTC spring.datasource.username=ssafy spring.datasource.password=ssafy diff --git a/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml b/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml index b994f53..fc40b51 100644 --- a/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml @@ -1 +1,8 @@ - \ No newline at end of file + + + + + + \ No newline at end of file diff --git a/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml b/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml index d5660c4..e0ec1c0 100644 --- a/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml @@ -3,10 +3,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + INSERT INTO quiz_room() @@ -16,10 +17,11 @@ + parameterType="QuizRoomMember" + > INSERT INTO quiz_room_member(member_id, room_id, is_host) - VALUES(#{memberId, roomId, isHost}); + VALUES(#{memberId}, #{roomId}, #{isHost}); @@ -39,13 +41,10 @@ - - DELETE FROM quiz_room_member - WHERE room_id = #{roomId} - + DELETE FROM quiz_room WHERE room_id = #{roomId}; - \ No newline at end of file + \ No newline at end of file diff --git a/codeBoy_backend/src/main/resources/mappers/ScoreMapper.xml b/codeBoy_backend/src/main/resources/mappers/ScoreMapper.xml index b994f53..d0b38ce 100644 --- a/codeBoy_backend/src/main/resources/mappers/ScoreMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/ScoreMapper.xml @@ -1 +1,8 @@ - \ No newline at end of file + + + + + + \ No newline at end of file diff --git a/codeBoy_backend/src/main/resources/mappers/UserMapper.xml b/codeBoy_backend/src/main/resources/mappers/UserMapper.xml index b994f53..39d9eb4 100644 --- a/codeBoy_backend/src/main/resources/mappers/UserMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/UserMapper.xml @@ -1 +1,8 @@ - \ No newline at end of file + + + + + + \ No newline at end of file From 2901bbd0146101aa3cd14cf6d660ac34c1a337e1 Mon Sep 17 00:00:00 2001 From: mingeung Date: Wed, 26 Nov 2025 14:13:21 +0900 Subject: [PATCH 06/61] =?UTF-8?q?fix=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20api=20=EB=B0=98=ED=99=98=EA=B0=92=20roomId?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java | 2 +- .../com/codeboy/mvc/model/service/QuizRoomService.java | 2 +- .../com/codeboy/mvc/model/service/QuizRoomServiceImpl.java | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java index 20a2257..4509bad 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java @@ -10,7 +10,7 @@ public interface QuizRoomDao { //quiz_room 테이블. 퀴즈룸 생성. 생성된 퀴즈룸 id 반환 - public int insertQuizRoom(QuizRoom room); + public void insertQuizRoom(QuizRoom room); //quiz_room_member 테이블에 값 넣기 (퀴즈방 입장) - 참가자/호스트 public int insertMemberToQuizRoom(QuizRoomMember quizRoomMember); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java index 175a381..a538964 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java @@ -14,7 +14,7 @@ public interface QuizRoomService { public List getQuizRoomList(); //퀴즈 방 만들기 -> 생성된 퀴즈방 id를 return - public int createQuizRoom(); + public long createQuizRoom(); public List getOneQuizRoomMember(long roomId); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java index 244e67d..9ec89a0 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java @@ -28,9 +28,11 @@ public List getOneQuizRoomMember(long roomId) { } @Override - public int createQuizRoom() { + public long createQuizRoom() { QuizRoom room = new QuizRoom(); - return quizRoomDao.insertQuizRoom(room); + quizRoomDao.insertQuizRoom(room); + //생성된 채팅방 id 리턴 + return room.getRoomId(); } @@ -50,5 +52,4 @@ public boolean deleteQuizRoom(long roomId) { boolean ok = quizRoomDao.deleteQuizRoom(roomId); return ok; } - } From 92d0d91a81de1221ef3a57b9e554809a903c95e2 Mon Sep 17 00:00:00 2001 From: mingeung Date: Wed, 26 Nov 2025 14:29:01 +0900 Subject: [PATCH 07/61] =?UTF-8?q?feat=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=B0=B8=EC=97=AC=20api=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=A1=B4=EC=9E=AC=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/codeboy/mvc/model/dao/QuizRoomDao.java | 3 +++ .../codeboy/mvc/model/dto/JoinQuizRoomRequest.java | 14 ++++++++++++++ .../codeboy/mvc/model/service/QuizRoomService.java | 3 +++ .../mvc/model/service/QuizRoomServiceImpl.java | 4 ++++ .../src/main/resources/mappers/QuizRoomMapper.xml | 7 +++++++ 5 files changed, 31 insertions(+) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/JoinQuizRoomRequest.java diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java index 4509bad..00c705c 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java @@ -30,4 +30,7 @@ public interface QuizRoomDao { //퀴즈룸 삭제 public boolean deleteQuizRoom(long roomId); + //퀴즈룸 존재하는지 확인 + public int existsQuizRoom(long roomId); + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/JoinQuizRoomRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/JoinQuizRoomRequest.java new file mode 100644 index 0000000..4b8b913 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/JoinQuizRoomRequest.java @@ -0,0 +1,14 @@ +package com.codeboy.mvc.model.dto; + +import lombok.*; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class JoinQuizRoomRequest { + private long memberId; + private long roomId; + +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java index a538964..281d61c 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java @@ -23,4 +23,7 @@ public interface QuizRoomService { //퀴즈룸 삭제 public boolean deleteQuizRoom(long roomId); + + //방 존재 여부 + public boolean existsQuizRoom(long roomId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java index 9ec89a0..2ae9b35 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java @@ -52,4 +52,8 @@ public boolean deleteQuizRoom(long roomId) { boolean ok = quizRoomDao.deleteQuizRoom(roomId); return ok; } + @Override + public boolean existsQuizRoom(long roomId){ + return quizRoomDao.existsQuizRoom(roomId) > 0; + } } diff --git a/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml b/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml index e0ec1c0..a3c6a37 100644 --- a/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml @@ -46,5 +46,12 @@ WHERE room_id = #{roomId}; + + + \ No newline at end of file From 3dae53c03a2663d2d1e05599dab15e1c13341ab1 Mon Sep 17 00:00:00 2001 From: mingeung Date: Wed, 26 Nov 2025 14:31:59 +0900 Subject: [PATCH 08/61] =?UTF-8?q?feat=20:=20getQuizRoomList,=20getQuizRoom?= =?UTF-8?q?Members=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .classpath | 44 ++++++ .settings/org.eclipse.jdt.apt.core.prefs | 2 + .settings/org.eclipse.jdt.core.prefs | 12 ++ .settings/org.eclipse.m2e.core.prefs | 4 + ....eclipse.wst.common.project.facet.core.xml | 4 + .../org.springframework.ide.eclipse.prefs | 2 + .../codeboy/CodeBoyBackendApplication.class | Bin 0 -> 839 bytes .../CodeBoyBackendApplicationTests.class | Bin 0 -> 838 bytes bin/com/codeboy/common/Category.class | Bin 0 -> 1015 bytes bin/com/codeboy/common/Status.class | Bin 0 -> 996 bytes .../codeboy/mvc/config/SwaggerConfig.class | Bin 0 -> 1644 bytes .../mvc/controller/MemberController.class | Bin 0 -> 1396 bytes .../codeboy/mvc/model/dao/CommentDao.class | Bin 0 -> 379 bytes .../mvc/model/dao/IncorrectNoteDao.class | Bin 0 -> 348 bytes bin/com/codeboy/mvc/model/dao/MemberDao.class | Bin 0 -> 387 bytes .../codeboy/mvc/model/dao/ProblemDao.class | Bin 0 -> 308 bytes .../codeboy/mvc/model/dao/QuizRoomDao.class | Bin 0 -> 525 bytes bin/com/codeboy/mvc/model/dao/ScoreDao.class | Bin 0 -> 380 bytes .../mvc/model/dao/UserIncorrectNoteDao.class | Bin 0 -> 372 bytes .../mvc/model/dao/UserProblemDao.class | Bin 0 -> 628 bytes bin/com/codeboy/mvc/model/dto/Comment.class | Bin 0 -> 1086 bytes .../codeboy/mvc/model/dto/IncorrectNote.class | Bin 0 -> 1019 bytes bin/com/codeboy/mvc/model/dto/Member.class | Bin 0 -> 1153 bytes .../mvc/model/dto/MemberUpdateRequest.class | Bin 0 -> 1037 bytes bin/com/codeboy/mvc/model/dto/Problem.class | Bin 0 -> 1146 bytes bin/com/codeboy/mvc/model/dto/QuizRoom.class | Bin 0 -> 956 bytes .../mvc/model/dto/QuizRoomMember.class | Bin 0 -> 1059 bytes .../mvc/model/dto/UserIncorrectNote.class | Bin 0 -> 1039 bytes .../codeboy/mvc/model/dto/UserProblem.class | Bin 0 -> 1216 bytes .../mvc/model/dto/UserProblemSet.class | Bin 0 -> 1003 bytes bin/com/codeboy/mvc/model/dto/UserScore.class | Bin 0 -> 981 bytes .../mvc/model/service/CommentService.class | Bin 0 -> 327 bytes .../model/service/IncorrectNoteService.class | Bin 0 -> 345 bytes .../mvc/model/service/MemberService.class | Bin 0 -> 367 bytes .../mvc/model/service/ProblemService.class | Bin 0 -> 327 bytes .../mvc/model/service/QuizRoomService.class | Bin 0 -> 639 bytes .../model/service/QuizRoomServiceImpl.class | Bin 0 -> 1135 bytes .../mvc/model/service/ScoreService.class | Bin 0 -> 321 bytes .../model/service/UserProblemService.class | Bin 0 -> 339 bytes .../mvc/controller/QuizRoomController.java | 147 ++++++++++++++++++ pom.xml | 19 +++ target/classes/META-INF/MANIFEST.MF | 4 + .../maven/Backend/Backend/pom.properties | 7 + .../META-INF/maven/Backend/Backend/pom.xml | 19 +++ .../codeboy/CodeBoyBackendApplication.class | Bin 0 -> 723 bytes .../classes/com/codeboy/common/Category.class | Bin 0 -> 1015 bytes .../classes/com/codeboy/common/Status.class | Bin 0 -> 996 bytes .../codeboy/mvc/config/SwaggerConfig.class | Bin 0 -> 1317 bytes .../mvc/controller/MemberController.class | Bin 0 -> 1177 bytes .../codeboy/mvc/model/dao/CommentDao.class | Bin 0 -> 379 bytes .../mvc/model/dao/IncorrectNoteDao.class | Bin 0 -> 348 bytes .../com/codeboy/mvc/model/dao/MemberDao.class | Bin 0 -> 387 bytes .../codeboy/mvc/model/dao/ProblemDao.class | Bin 0 -> 308 bytes .../codeboy/mvc/model/dao/QuizRoomDao.class | Bin 0 -> 525 bytes .../com/codeboy/mvc/model/dao/ScoreDao.class | Bin 0 -> 380 bytes .../mvc/model/dao/UserIncorrectNoteDao.class | Bin 0 -> 372 bytes .../mvc/model/dao/UserProblemDao.class | Bin 0 -> 628 bytes .../com/codeboy/mvc/model/dto/Comment.class | Bin 0 -> 1105 bytes .../codeboy/mvc/model/dto/IncorrectNote.class | Bin 0 -> 1045 bytes .../com/codeboy/mvc/model/dto/Member.class | Bin 0 -> 1172 bytes .../mvc/model/dto/MemberUpdateRequest.class | Bin 0 -> 1070 bytes .../com/codeboy/mvc/model/dto/Problem.class | Bin 0 -> 1172 bytes .../com/codeboy/mvc/model/dto/QuizRoom.class | Bin 0 -> 978 bytes .../mvc/model/dto/QuizRoomMember.class | Bin 0 -> 1095 bytes .../mvc/model/dto/UserIncorrectNote.class | Bin 0 -> 1076 bytes .../codeboy/mvc/model/dto/UserProblem.class | Bin 0 -> 1241 bytes .../mvc/model/dto/UserProblemSet.class | Bin 0 -> 1040 bytes .../com/codeboy/mvc/model/dto/UserScore.class | Bin 0 -> 1000 bytes .../mvc/model/service/CommentService.class | Bin 0 -> 327 bytes .../model/service/IncorrectNoteService.class | Bin 0 -> 345 bytes .../mvc/model/service/MemberService.class | Bin 0 -> 367 bytes .../mvc/model/service/ProblemService.class | Bin 0 -> 327 bytes .../mvc/model/service/QuizRoomService.class | Bin 0 -> 639 bytes .../model/service/QuizRoomServiceImpl.class | Bin 0 -> 1035 bytes .../mvc/model/service/ScoreService.class | Bin 0 -> 321 bytes .../model/service/UserProblemService.class | Bin 0 -> 339 bytes .../CodeBoyBackendApplicationTests.class | Bin 0 -> 551 bytes 77 files changed, 264 insertions(+) create mode 100644 .classpath create mode 100644 .settings/org.eclipse.jdt.apt.core.prefs create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 .settings/org.eclipse.m2e.core.prefs create mode 100644 .settings/org.eclipse.wst.common.project.facet.core.xml create mode 100644 .settings/org.springframework.ide.eclipse.prefs create mode 100644 bin/com/codeboy/CodeBoyBackendApplication.class create mode 100644 bin/com/codeboy/CodeBoyBackendApplicationTests.class create mode 100644 bin/com/codeboy/common/Category.class create mode 100644 bin/com/codeboy/common/Status.class create mode 100644 bin/com/codeboy/mvc/config/SwaggerConfig.class create mode 100644 bin/com/codeboy/mvc/controller/MemberController.class create mode 100644 bin/com/codeboy/mvc/model/dao/CommentDao.class create mode 100644 bin/com/codeboy/mvc/model/dao/IncorrectNoteDao.class create mode 100644 bin/com/codeboy/mvc/model/dao/MemberDao.class create mode 100644 bin/com/codeboy/mvc/model/dao/ProblemDao.class create mode 100644 bin/com/codeboy/mvc/model/dao/QuizRoomDao.class create mode 100644 bin/com/codeboy/mvc/model/dao/ScoreDao.class create mode 100644 bin/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.class create mode 100644 bin/com/codeboy/mvc/model/dao/UserProblemDao.class create mode 100644 bin/com/codeboy/mvc/model/dto/Comment.class create mode 100644 bin/com/codeboy/mvc/model/dto/IncorrectNote.class create mode 100644 bin/com/codeboy/mvc/model/dto/Member.class create mode 100644 bin/com/codeboy/mvc/model/dto/MemberUpdateRequest.class create mode 100644 bin/com/codeboy/mvc/model/dto/Problem.class create mode 100644 bin/com/codeboy/mvc/model/dto/QuizRoom.class create mode 100644 bin/com/codeboy/mvc/model/dto/QuizRoomMember.class create mode 100644 bin/com/codeboy/mvc/model/dto/UserIncorrectNote.class create mode 100644 bin/com/codeboy/mvc/model/dto/UserProblem.class create mode 100644 bin/com/codeboy/mvc/model/dto/UserProblemSet.class create mode 100644 bin/com/codeboy/mvc/model/dto/UserScore.class create mode 100644 bin/com/codeboy/mvc/model/service/CommentService.class create mode 100644 bin/com/codeboy/mvc/model/service/IncorrectNoteService.class create mode 100644 bin/com/codeboy/mvc/model/service/MemberService.class create mode 100644 bin/com/codeboy/mvc/model/service/ProblemService.class create mode 100644 bin/com/codeboy/mvc/model/service/QuizRoomService.class create mode 100644 bin/com/codeboy/mvc/model/service/QuizRoomServiceImpl.class create mode 100644 bin/com/codeboy/mvc/model/service/ScoreService.class create mode 100644 bin/com/codeboy/mvc/model/service/UserProblemService.class create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java create mode 100644 pom.xml create mode 100644 target/classes/META-INF/MANIFEST.MF create mode 100644 target/classes/META-INF/maven/Backend/Backend/pom.properties create mode 100644 target/classes/META-INF/maven/Backend/Backend/pom.xml create mode 100644 target/classes/com/codeboy/CodeBoyBackendApplication.class create mode 100644 target/classes/com/codeboy/common/Category.class create mode 100644 target/classes/com/codeboy/common/Status.class create mode 100644 target/classes/com/codeboy/mvc/config/SwaggerConfig.class create mode 100644 target/classes/com/codeboy/mvc/controller/MemberController.class create mode 100644 target/classes/com/codeboy/mvc/model/dao/CommentDao.class create mode 100644 target/classes/com/codeboy/mvc/model/dao/IncorrectNoteDao.class create mode 100644 target/classes/com/codeboy/mvc/model/dao/MemberDao.class create mode 100644 target/classes/com/codeboy/mvc/model/dao/ProblemDao.class create mode 100644 target/classes/com/codeboy/mvc/model/dao/QuizRoomDao.class create mode 100644 target/classes/com/codeboy/mvc/model/dao/ScoreDao.class create mode 100644 target/classes/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.class create mode 100644 target/classes/com/codeboy/mvc/model/dao/UserProblemDao.class create mode 100644 target/classes/com/codeboy/mvc/model/dto/Comment.class create mode 100644 target/classes/com/codeboy/mvc/model/dto/IncorrectNote.class create mode 100644 target/classes/com/codeboy/mvc/model/dto/Member.class create mode 100644 target/classes/com/codeboy/mvc/model/dto/MemberUpdateRequest.class create mode 100644 target/classes/com/codeboy/mvc/model/dto/Problem.class create mode 100644 target/classes/com/codeboy/mvc/model/dto/QuizRoom.class create mode 100644 target/classes/com/codeboy/mvc/model/dto/QuizRoomMember.class create mode 100644 target/classes/com/codeboy/mvc/model/dto/UserIncorrectNote.class create mode 100644 target/classes/com/codeboy/mvc/model/dto/UserProblem.class create mode 100644 target/classes/com/codeboy/mvc/model/dto/UserProblemSet.class create mode 100644 target/classes/com/codeboy/mvc/model/dto/UserScore.class create mode 100644 target/classes/com/codeboy/mvc/model/service/CommentService.class create mode 100644 target/classes/com/codeboy/mvc/model/service/IncorrectNoteService.class create mode 100644 target/classes/com/codeboy/mvc/model/service/MemberService.class create mode 100644 target/classes/com/codeboy/mvc/model/service/ProblemService.class create mode 100644 target/classes/com/codeboy/mvc/model/service/QuizRoomService.class create mode 100644 target/classes/com/codeboy/mvc/model/service/QuizRoomServiceImpl.class create mode 100644 target/classes/com/codeboy/mvc/model/service/ScoreService.class create mode 100644 target/classes/com/codeboy/mvc/model/service/UserProblemService.class create mode 100644 target/test-classes/com/codeboy/CodeBoyBackendApplicationTests.class diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..dea924c --- /dev/null +++ b/.classpath @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.settings/org.eclipse.jdt.apt.core.prefs b/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 0000000..d4313d4 --- /dev/null +++ b/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=false diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e82d82e --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 +org.eclipse.jdt.core.compiler.compliance=17 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.processAnnotations=disabled +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=17 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..48ff4f3 --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ + + + + diff --git a/.settings/org.springframework.ide.eclipse.prefs b/.settings/org.springframework.ide.eclipse.prefs new file mode 100644 index 0000000..a12794d --- /dev/null +++ b/.settings/org.springframework.ide.eclipse.prefs @@ -0,0 +1,2 @@ +boot.validation.initialized=true +eclipse.preferences.version=1 diff --git a/bin/com/codeboy/CodeBoyBackendApplication.class b/bin/com/codeboy/CodeBoyBackendApplication.class new file mode 100644 index 0000000000000000000000000000000000000000..ad03b8e5e31134a436212e6adcda934e19956bf4 GIT binary patch literal 839 zcmbVK(P|Sx6g`usO|nK)qixlKj1SV(hvubE#tMz72#bQL1@UQiGp5t-&Ru3Fk$jn8 zLErrhKSaE*2zXU{z|=broh=a;Vl_ORJNP2gclc|WDGPH5hL#(7Bdp-NA* z9q$)KW>V!1*#_zYtH)}l`kAtm{+r}jr(R&?iLu5%6AZX_qt?NZmL@OAc}Z@vQx?wH$w#Mh{fXR(OqI3d zWuoP8rvGXgRkTAQ|A)v0etge(e6O8aDi@2smczOGod~|totKV3T(w!a%jNQ&y}$P>%9+)?rmaS;N|5G1Ou)l zQy?1A)TR1`3GcuE&&AmZ6A;*ZJGI{A`jwrT(y+$;U}NPzOWcST`Z2%*@MiI{0yX|x z#tO#wzVAk#(f(FpIvfKA{C|~W`wWGf=yKJyX~th`PjzYGZ^ zxO3nqA;!z2LXBDu_INzseD*gp-+p}h0^l)rT8IShXH*O_n(CBRgQsjqv>K`GMBC{> zS>`5F-jJQ>%2zEk1UBbtsRp^Sv%%|ht}`#td}OTgPXsRQ-a8a%1eO*$0=-l0bLYsl zaarK|TkCX1`BG0Mzg?QVenFOw(p(qSzKlDQV=YZllJk<>Y;V3`ewit2$;(vBKlx{X zRq2eK9XVC#_vB92ri^RMh{y*~Yar5-RMM|X&HNWaVzhCkiw#^A*xpS}6_0)R%P>@= zml&&GEs9jTiDHog{e&`=A1Y^p|NFAxk4+`;Ao>563jIeh{iwmzbl?Bq$oTaZ}*g`HiUiaG`vGcuWhI=@%yGx_kZv?S=C23?=_IVF(GH z9-c}d;o4j{_p|FKMd%!i0M!3$WfZAqz WmhHwGw$2*12)8&t!tK9&cYvSkP2!0F literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/common/Category.class b/bin/com/codeboy/common/Category.class new file mode 100644 index 0000000000000000000000000000000000000000..fda0c6a3bb7ff49979007ce4fc0e46c20e728134 GIT binary patch literal 1015 zcmah{-*3`T6#gy+3al_h#~f^P>Qv|^ga>^Aml^C9G6vB)65>;-6}$9@DP;-&m9mE| z8W*4aqm1WvZ1hF!L+?5FobNl|x##@;^Zg3ID^x^87>c@US9SNJF>ohz+P3Rdo0@M7 zU2h^H%8)tL&a|qfIm4>rjBSSHR_CCrbPih`MS0ii95QUQ7m(B$qUziB8-^vNb8@`h zd)+=!REEtD|3M`hx@9`1zsDey$~~fKlFS5RDUb*WS=?cWH)bjMQhP2`^*z%W)?4LX zl5+1#h#{VU$ep|d5pizamyke`sM@AubjJ3;@ZM_!%V5a0U0t(!nrCu9xJ*I7GD+}1 znbidvT z^>uSajWLLUi0&tbS{OF#y}a;sc{?QuPf%uf5k@yHZ8WNfO5W1Vq`vvxITm*8!xr5!{eEt{BG28?I literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/common/Status.class b/bin/com/codeboy/common/Status.class new file mode 100644 index 0000000000000000000000000000000000000000..c5f01afd7f810a15fce7faa700b45eb370ae8cbd GIT binary patch literal 996 zcmaJ$S(8-T(%HQh>TryYeKv#wPKfkm{OMTuasSE z(YSc+k20ROu+f{*i=NNtoaemf{QdXy2EcpNMZ_42hUYX4@3T4drX(H5a~o=)2a~ag zI79Yazt9`D?v5HAcj7Q4kJ_hQt;106-HU88q`Ljv#7w7ucD$_}_0BpfL*>(IT+6U6 z*9s08glbJ=h_{Jb3JD1e>oRh9Kpa|<Q()BxAAZHBb&`})-IzD*gF=m;mnbJGZ#-N;n8E*gtL3@My^VQ55Q zi^*#%UY3timGKHShPP2{+t$b9W~AX=u_bxFdD^L@dK2F;KUn;^GV>#;^DLT3wMH%- zjZcxiNHLCVt)O+#Jlvc7AS`8DAR z*-PX@<54^`HWI%nB+QUk2k{v;)JtssAVdsB`e(y#aja3d66vKd!lQIsiyr&r=bS`k zr*ehz5}c$2q8ftaP#00*WQph#Y%SpLs5FNcX4o8j6qK7mi!(YF%GY?h`<)_lD)VaW jjzXID^LkN3p&Z^z$}{B}Z~lPYkBdPGYwln-lzaaHTgTO3 literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/config/SwaggerConfig.class b/bin/com/codeboy/mvc/config/SwaggerConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..2e549938d30bd5818239c54fa868da3fa4e703f0 GIT binary patch literal 1644 zcmd^Yx15Qbl;p_^<|T0+ZL`Ea42h zv41RjJ!xCxEI^TA^+=3FV<2>|vDZ10v13?#th91Z85U~w1BPOYd;*jiR!+6gtu?lU zC02O(PFtCo!AKr*+BH=J;gr!lwWc$WN%n|`<#u0km88ZxZftKmORdtqt`&(qHueLL zh1SOLj^sa`{`M7RW|{u6V$!>zoqXl_(z!ESaCef*u>4F4om0r~lD$;woj1GxMAf49 z8!ffVX4v_8B+~WGAs4CI)m>Ao^R6`scl3|1ou46v=F*im^L2YcqOyzzI1&1{!?KSv zHk~aAQNnTs7jThby%wF)w(mSJO;6)Wq_liJOghrG1p&rTjZ7>C2f`|!PZx`>uQG-Q z(L4vC$q<;y92k~r^=LX2THkm()J`RGSC3St$bZM9I-Wh*FGhaC%@VFLR+-}*{5L#M zL#JRdl&GP8_SB}E4E;IUG@Fz;cw-3n&Ctg3g&I?G2Iy_imWS!gX>JDCr2EcqAK)H+ z!;}Mt%Bu3uc)h{{)5EntPB*LeLZ#me|O z#3fWIW4MepQms!_SLpY=+tnPmHWB4CcZ|`d z1gk99e5(wmIvV4UQ}9Ga!b+`pVssE;oId4Vd2ona#)&qTYctwR6C>5=z=#+>YV)3l zLMd%|fc&?o|HDM;g;(!kYNu6R0O3}1!R;hLuiV2A8R5GkNvI}Ezyq-iv8ONUt4m#t zwyZTW$Sf`i+@B~bK5=wif5@duky_bAmBoB_h|0+Veq7N&N6m|Xb-JEeIT8U^EYI$-peS>7(NSu6Fp#eTCAy zy7w6>-;Xg>S{(-He~s442@0-2oiqkl;Tn0mPI8fvdcz6yId?hQPu$&H;I6U2T@G%M QO%85D!`YH_hjtF|3pKl^3IG5A literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/dao/CommentDao.class b/bin/com/codeboy/mvc/model/dao/CommentDao.class new file mode 100644 index 0000000000000000000000000000000000000000..26d5a0eaaf480c04175c6c88788b338619b54f5b GIT binary patch literal 379 zcma)&!Ab)`5Jaovnl;fi0sRD#e_s-gMi1kB?QWxWDz{CX5PCB^uXJo{CY=9vT;zX{ z#4X9>O1{Z#)o>j*aD>y*KZ4_D3AQh#j=T+Kawq@Li7<(+KMQSb_|7`v9DH|h_H|H~ jK-iJ`fJ7?UMOSnxs)IezJ@jQk*x$Sd$Ye)2TssDzFa~EB literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/dao/IncorrectNoteDao.class b/bin/com/codeboy/mvc/model/dao/IncorrectNoteDao.class new file mode 100644 index 0000000000000000000000000000000000000000..da97c4b7d147a368c48edec7d8a671db9f7dc557 GIT binary patch literal 348 zcmZ`#%Sr=55Ufs2*2D*bsK1bSaIQkslL#)03IXr4lO{}<-G}e&Q#h5v#?^GYbPJbt?Y`o!_$N{l zv$dW*sLiG3CW^m*IMPe zT&mY(#l{hOSy^-Ce(wmk@$4U%YhmNjyU1$JMc>LM@$86RxGF1`+F~i z#8dyN`AD_n_S1d*e3J6!6?6VVm3!g?3JQ5~bvoq{XUGk#X zIvWYkt@8?(K?1+z*LKQ5YMz_uN@@1lYks!qV&yrn+L#g2RaMp|c8w#f@7sR6$-1f@ t|Egyn8Zlf+*I4&edCeIAA2mCb=@SSK`VWBg#wYYuC#rfFD5Yl_{sLxNTG0Ri literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/dao/QuizRoomDao.class b/bin/com/codeboy/mvc/model/dao/QuizRoomDao.class new file mode 100644 index 0000000000000000000000000000000000000000..b99a818ca4052769a7efa3785e17e5a458c6da6f GIT binary patch literal 525 zcma)(-Acni5QWdywy{-Xf5bNsk_+8iA^sqUP>B?+c)v-PvSpKnWK+;b^TG%4p~Okr z8leik+TEGi`R2^|{CfWYaET)a4Th80Bs?}#8JSm}EMlI}UGu3h{IO7PPsSv-!Z>I$ z^yXqAxEAS*kE6MaErYAlTxND%$*|-3BZlK;_(3L-%$`l1KJ~(Xc(&#(zXkpaLqC_A zKsQ>~JqDg1R+AJ~X&$QF1`M5vnx(=PnPfQMD7e^y8eCDE6>pr%nm6=De*mvHquWqc z+Dev7dzSVWsOjC8n!6KIWU;(cnzZ!RbC3yVrRp{VZJ7)NTI5L!ZIs?P*sabEx|H9e XYy literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/dao/ScoreDao.class b/bin/com/codeboy/mvc/model/dao/ScoreDao.class new file mode 100644 index 0000000000000000000000000000000000000000..2d9d910b121141924686a3167f38c00a4d4c9c9c GIT binary patch literal 380 zcma)&K}*9x6olv1*x1(E;!p6DTzqG#3W5lQKo3Fh+s#t8Y_gJU3jQ?@{s4cJ_`0YR zMDX_Zn_*^|_m9^%05_PY7!WSBuUY%bto;kuJI%G+jw|K4)V?+M%BM&O^R3z`cBWxgcL`sYf8Lt$L{zSZWzI;ow0&v3c_-H<>ylKp^0 dRyoE{4nm3(;Ul2~jO9JSY2?$rF3MR{W}m~7XP*E7 literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.class b/bin/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.class new file mode 100644 index 0000000000000000000000000000000000000000..caf04d0bfc5752611a86bb1ce0e231c36c16ae12 GIT binary patch literal 372 zcmZ`#%T5A85Ud7a0Ut5pB>n(gm=6Fw851`fFd=%M9Xe#l>`pQ}OX9D2@B{oPV=rA)H2@+Nw}}r$#8V?8hq}!s0hPxI?47&b+k@pwu&=Ce`PnNj&)$d{Qt&0 zJ7X>WSv$zj9z|*-o;mWV?+Kl8noizj$(EAnq({PFZ^Z(HEPOp|&+YuXFQyW(mB)>cCMYr8{0{@9&_KP5rmSO7kB{jwK ze)jL9HgLCoNoi%B&AMcx?B#~u!e1~|wGx-Ly?C8S{ZHJH zK!Q6z3NhXds!$LSHxA<&&wMju&3yj;21qhf9{k(%>ZEqJWZ&g0CP zcx03k+6B-g&^u!b7UxV)KlwqaB6_^plIkv9nT7 z4+(58GoLXh2yEAo@F-Nt)6HZ_U_Zg7|DD;$ zvS@7PmWvnCm+OpbMnCX$BCz*%t{pP+NH1h5vBA*OqaqR350iQYp3j*mxs`>dm*?~9 z*b%gqtPB^uVN#E&0l`v-(5~(gY*xBc`SAzh?5^P1Mejq* zCa9w?&^zt-Kf(653VRLDRu$QR>u7gs6x@KDReY~HZ^3QUyV&^-YKk&Ixr?$7@Doi# BI2Zr` literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/dto/IncorrectNote.class b/bin/com/codeboy/mvc/model/dto/IncorrectNote.class new file mode 100644 index 0000000000000000000000000000000000000000..7718f2a8658b6ed4da8e03ca755ccc79e496ead5 GIT binary patch literal 1019 zcmd5*OK%e~5FRHXk8L1r`ruJO=0tm8FFjFODXIVkt%5{KC5~RNmAKfRmDh>X|HK^$ zB)IoSRm^UJN>v2q#=$e6Jx|SiKEL?#4FC>+x1h%0sYDw~%v6eJv7O7<5;k!bFdjOI z-YXeK7*q=y3|3FYT*OAWN&GfFB@2U|{?%)kF<@^Pw5_tK^5wOYdrXb8C2qdZPKQGV z^_|@l28|=C)q>lUy_ZLAI*1FJvK7-AjvD1|u@UYGaf zV|)2DpILm6(t)*^Pn!XIpEh4!> z);;oMq@%CU{m{Sj8CJhnG3z9om8A|Fgu4qb*o3Xhez%hM;6CXss`P;LHl2rb9?^LW F@B>rAD4_rV literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/dto/Member.class b/bin/com/codeboy/mvc/model/dto/Member.class new file mode 100644 index 0000000000000000000000000000000000000000..95a6fbbfa5f836b54975d0ec5dc01c12f7c20705 GIT binary patch literal 1153 zcmd5*OK%e~5FUp-H-WTiS{~(LN)O*-+cT2=?efnhCu@=1ZbjVnCJHZYNhlGg;l%0i z6_+tL4X6@WIb?Gdrc6!4*YP1w9D%0v;oS)V@{&MBAm~LWypc0PO&=mLW7fXc2IEa7 zk|V_=Cs5;(iIhNK#Z=|lQ|8dwFYnuTX*d>=TgPOE8R`gJZV7BgzgCM_Y88%r5NT~J zoI5@#bJZUSCEODN=LUBV2vm3QT@6?#&^@W~nK9Zl;UXa)_LbpQr*l3jI+BT$IiVHJ zjE++-?E@OL#xqWZ%(QV-Xqqskw4*VnKQEqQq*})M=s#iY>7kk09j&Z0dE&G=qb}++ zWz-#KJZKHm^xrPL;Lh+Om^;}~N{d$_Nm_daGNXoJttf7{#m2$#Nk?k4VaAF07r g#GR4_*WkL3-|#!dx&St?qAj$yaBbtdjq47;503go@c;k- literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/dto/MemberUpdateRequest.class b/bin/com/codeboy/mvc/model/dto/MemberUpdateRequest.class new file mode 100644 index 0000000000000000000000000000000000000000..61a0d62b6dd47d1c9e43200ef36b7528534d6ecf GIT binary patch literal 1037 zcmd5*OK;Oa5S~raJlsIq^g*G3mRmW1FPwNuQ3VLe1gU8&aa^xQ$+r7&*Xv0APu!6} zf;&G7F?Nb7lnUsL!#uq6%|kPvzyJ9B6#!lU??8jWBk4>mU52SUkIh`hhI}1o!Nu>; zr09?GOawf@vl5HYffj?c6EPRD7IqrHPft(=23@P<=~x(KFibAPli-z|K4Z{O8G{ux zLTLu==gO+^l0kFt;W2~OK6UKC4F-eD%vat!--Q8VACIiZ!s$6?oMz3H7C|}7bMI1( zrg+Mu-r)?nGP(1CE61g<)&-s-|CRU~LOYYX)BglD(t6~l#lEve@TCmSUojXDjtd^n zbBuapcRlj?gEi<9I_aIRg$7RK>LqR93DC4Bi z$HJ@X`{J<`W~yKiC)Xk&u-)1+ zLi8Xay-Lw1gk)r+FVO!my!i>%zSTJ!q}z3*37h2i7bw_*?K*y|);n;U>^60}Lw1+s LF3CNT`v5-yD_$>T literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/dto/Problem.class b/bin/com/codeboy/mvc/model/dto/Problem.class new file mode 100644 index 0000000000000000000000000000000000000000..5cea3fc7ea50ed06d0bb0231c971f4e0daa0482d GIT binary patch literal 1146 zcmd5*OK%e~5FUp#k8L0&Y0IM&oVJK^VFmQWONzonMXOSgQi-G2u@aYEPvmui@}IaP zfdqGc6k>L>Bvh$*+&I|ZH=gnAc=nrb-#>i;fX8sF3HDw36D1vk>Tv4c?=fI688mYHsY;~PL#NTuVKBegbyl1H zLk49zKrPkX8M`-Q_h)R6K}ne8y|N4{QaIH|J7KUH{8}*a7>(b_-ITlZNE_{*FgUk+ z`Bacq$^oIK+4VNz?(hZ9nOtNt_)?hxUxRxI-?un+%m#ZAa0+U3j6KQ-8|Z z{i`53P_g)ZeI7L7at&7C3WK%XMPa4?yB=tx4n}dP?2#b#rV2zUqGMroYUhVVH_!=# z?NeepQ~e|U6n6@*c)22;n)*7PAz4>H83rONL#}z2R5|oG)piEYZ)f~MXmvgM;cs|DqP^WmB zUh3&Z+8bo;QC3FieTL@S#@a`?^fk+QmG)BRS%MAXwP_SwgU!r;J=<>pCtRnBT7+A) LwrTCqx(Vu=vbeF1vq16d z%Dg`$vR!B+te(iZjC1Lx@vHPitANn)?A*@~@FgpcjWgjX!qU$DV}$k|m+8VX!tgxt znfK&-u!8vEjq|#se6BOW4HPDq!H^S$r!?2Ld?cd&(M$_t3-Uo25=uHpL8MxoCH@kT zlTGQ}e-d>-V?QnT$d$oYDvW}mM-x6Nv5cFkLCw~>BX4=X>_ZL9~ z!vS<*6=7p1Ip60bc;lwK^}dIRar&ULsrE;bSBNl5NXh(IdQ`R59$UGwhk*7jMe*YZc4*XjBA24G~yT5k_$`Vg6qk}QM0+1EC$-Z z#n=|G84kncOqa@=qUI=U1CyM85JC&CK&L^-)9JCL&)P%wBHz(xh~AC{AK~g()>?3l n&rai6f)V4vA_~@Ez431}=O$d|dy^~Q;QJ=aEtV~o+WVP=)EM+7nowe*Vmt}WM23cN8YUjY z*M)w+k7!;h6D!w*I)jyCF%e-Z>?nK{A1mp}^=^)~n=oK67_>|kRW2Kjl2kzF&oQT% zUUZu0F=DEO-6q}xZMA>IV4=Tt#Gt-IH)%qLLFbhH#5r^=SY_-<9bfOYYZ^(2i zyhh72hjFS*exC>JgR$b;WavEC$fd9rJ&zUt892vC(Zu-nKVj|Rz>V@9w7GYM^yq$b zFYb{G?oTomv6u`=S%_X}VddP}efYYf)=zjS}-owlRxvfrIZ zTeVk|T00QbLI&LkrAUv2)8%^RtoyOf8Qh7^D_l}mFvP-1^;DNxd-J-!TZ)Up=6+$l zHfq;Sbgt>RK`E9>Qgm7`I@1tJyB3`-JGooYw73jz ztV0bhK!Z>Xnlsy)*){~^r;kMyT%!3Rt?p42BO82%eM)&7-gz6zUUH|WG`WUte>LE|P34)6nEyE3o< literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/dto/UserIncorrectNote.class b/bin/com/codeboy/mvc/model/dto/UserIncorrectNote.class new file mode 100644 index 0000000000000000000000000000000000000000..0db1604bdf205b67acee7fd68934917bb31d65e6 GIT binary patch literal 1039 zcmd5*OK%e~5FRHX*=$o%(l)%o+=>wFg%bg!r~(wU3W&6oIC{NS;uSC+u7nNn}M=UZ zm77?J&ME1q=v4<=47QHNN<^8k^XN@-OdbZ?#h=JY%7DFQ5Ex|=%0k!867<$#k||T( z+fTLC{yBr@-u)v6t$nK7flUVevjQ)iLl;1wv5$w=sT{MFN;!4B)S2)aEnn6N^Cvv) z9xN2sW{J*oja&+A(ep&{UxB|NGBgQ(_)kzXxll&@r5Wy#3+_*rD(p^i?B@AC+T6QB zdUWUD$60o$Oo6yVAL)qT`Y> z6|tyh5Z7y=bQ`J4rPIrjazyudZ54#siPr~C&p}*|wKD7Bjo=;-?dcOXp#hhmO;!Us zr#h%KeIJ@%NaqH59}|+14!=O}{owK^*!ot*Y}47UJWbdkyH}%N7lxJpYIR!gQN Q=?3XrB)3WKklY3M3A+I>)Bpeg literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/dto/UserProblem.class b/bin/com/codeboy/mvc/model/dto/UserProblem.class new file mode 100644 index 0000000000000000000000000000000000000000..df5b7b0208c5b79de657650ef79eee9dea9776bc GIT binary patch literal 1216 zcmd5*OK%e~5FUp#k8Mgq+J;9dxV)NjUfvX z2_(4lqY$&3B}o-f#EpYJpU0oaI?e&;5kO9BVT{`Pgq^v7ZLkIGSq6y zs2vZ4Q*MP}%k<*5RnD=uOtE*}9V1wai}3Y&EkrxRmniX&h`Ztn~)Yo9NxgTL@a`D>UBM vuY87U-&5{3&V_Vm1#Td&OjvLeXu7|X&bQz;+6HEL2kku^yEvLS_5gkXrN34G literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/dto/UserProblemSet.class b/bin/com/codeboy/mvc/model/dto/UserProblemSet.class new file mode 100644 index 0000000000000000000000000000000000000000..5b3cb6dd00e629cf3c30df7b6811b6b3e36ff7ac GIT binary patch literal 1003 zcmd5*OK%e~5FWQ7*=zzS=>t%Cm|NNdd*MU?DXIV!tqLM-C5~S2C~;ZaE3Y?F{}Xp4 zDwR7w3NgD2s-hwVZpa$Xc>H;0H1qlUkFS>i@B$unV2!~@S{+H7Vq(uDy^xV6JBw0p zqmu&NduNjj^%Q*vS`0SM#6m=wFtg}ga)#2At6YK|rVQ9y27yMMpsSAU=gKJmlEM0D z@03C7fHHKT&tPyB?Ui%Z1#pY8&nL!VVY3CMoNCKeCcLtS=S?NWGah!2=g5`Lt@B)2 zE`>4H^91?thf9de>coEfPf$}iM=kzP4EL4`?$2`!yGM57X2pRug?FX&)~&!#vh3d; zyg~1ARaBb!N>B(r*yuw5w;61Y;;VU1y;Ej3uI4?6mBFL3V#Bc@GBFs&R*LLYI8~j0 zIa_|N3I_Y}-x6}nAe`FLNqnuUsGG}teNq*}VE035ywZ4R7OGH`Zc>q@rW9oh;$|Qe ztCwOSoyse+QLy;h5D2psUvD+JgScsEZ8mKi!($-A(??sQbpzV9)u}ao5b9W$_K>_! z3B^c<7ts4Sy!izN-)iiT_I7=<4x4268x(B8c74B7?|0xX=^e^&kMu6deUb+x4*`Ax D+N~x_ literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/dto/UserScore.class b/bin/com/codeboy/mvc/model/dto/UserScore.class new file mode 100644 index 0000000000000000000000000000000000000000..484e95a1ab6b6a705208a3a0c9fd8f015af77d35 GIT binary patch literal 981 zcmd5*-D?yv5TCTy``Dhndj0UDDk&n=7x%>{YlWkzoGcZ*w%}tnJKUviGD|jh(ErJI zK|$aBql&Y8twkzY-y}@tm*khpF!Rgzv(H}vU=L&q76d%hWMfSkrgR$HnT{>vJkA2e zM2v|K)GZp8`jpMiJ3F;uAZPBLahnWEJM!-^8kr@vKG@l!1!V3Y5JCBbA zH1;`a3vLMLU50t-J^42Dg!p*mJeHKtFq525VR97=Iazp0bF}3%8FdaPD2*-12Wd!Z zqP)2H3nM3+(ueK|=)%n|bf7O_V<)-n=O}pN#=BL&dx>#)Fs;;asJMj!`Uz>3A1iOF_4#Ha zOiU@@QF09t?h1%TH1!%^nJVDQPkBD6QV_89Zt8-uICL{p8h&I@Nu(AMzp<8FX#+=G zPp%f5x7*3Qq&1uuZVv16FkH^C)ZP@8N?{vV=KQ4=cq~D)MlEQw=fA*pig;e;)l+5( z_R$yUzVEMmg4J&|ca7&}eXe2I3}HLn;L)$y7)k8A$Fwaq%I82$^Jf UhJ3h^>>c|=YF~(OEg4~O0JO|az5oCK literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/service/IncorrectNoteService.class b/bin/com/codeboy/mvc/model/service/IncorrectNoteService.class new file mode 100644 index 0000000000000000000000000000000000000000..eea54f05f9adda47609f4f9ddc26044b7c9de7fa GIT binary patch literal 345 zcmb7=KT88a5XIkI?s9sGCfHfpX^Jd}oqrlZ5RRmXq~BWy-Eemco6CV8D^Hmtx8>gsA;i~1w!}1*0y;fbgpmag!ox5W$56vj|5%9Ah$J7R#n0NO&28- zE^=pdIoI9>e+c8|(=G{j`SE1;gly(k-tdbJ_b>m$9|v+=K{(|fAe922Xev(aJdlhw cI9W>&ArlQ_$b+6}f7d5c&%_bVMI#LU05@?}6aWAK literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/service/MemberService.class b/bin/com/codeboy/mvc/model/service/MemberService.class new file mode 100644 index 0000000000000000000000000000000000000000..0d73745679abe03ce5252befb76b8de6438d3707 GIT binary patch literal 367 zcmah_%SyvQ6g{`bMr(ZFSELBe!ewwPDlLLR_mi1RoRVbfWRl{qx$p!0C~=xvL=@cI z7x$iX?s@-seFJcb;}|2tnXvZ;gmV0NKGW$K5&i)poz5NoB1>BYKPuj_q ztO!whv*t>=rIwzzY!~V6zeo?m#XUcF-1=+~oZHSRzA_aPPJcXpz7{_wgx`X7Kooq~ Z#W)m%7<)tB$7IL{NWuo;FvJm#J^_jsb_ofTC7q(Hta$kzA_Ki_mEW9g9ZI{0`MNAlO zWFti>t9LOkHd@t$_RLhKej>EScWXlY%o!P4=yZ{wO&H{+(yu#PXup!2M;PT!$#N~d z3I1;w*B@p}nC6!-JrJ^`+j*s5Oh~@@k30>uxCOKE*WgNli8W;>&K^ka54if|L4=Go UticD@tle{;aP6@p^jRYePO-yHxBvhE literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/service/QuizRoomService.class b/bin/com/codeboy/mvc/model/service/QuizRoomService.class new file mode 100644 index 0000000000000000000000000000000000000000..11f4bb1a533675bb422b1020a120c821fa2484fa GIT binary patch literal 639 zcmZuvO>Yx15Pfc&uO%dHNcje>dfHTN_lij9g%62n0l`A0a&sIjIP%(+>sZ9)!kvHjkRpJ(3q*Y9sX06f9N2DTWEg)LHHr*dL1(_$&og3dZ!NVil%rf*C2 z<(;)feuW#@Vc4DXB~LXsv-HhmE`?`kj)Yc5`BR4NWN^l?^OR&7Xfbp*+0UJ`u8C_5 z=O2ud3#*rM8dCumN^`HQi7%X;XjwdtqgH-tJpUZaaOWsihAQ&$!SEpVwz{IFm+>p< zKiTOsDKvMLLKLBi>uq$+|)fi8L8+8Vn7JUVv zMyAzJC)^-(xMHL4XrA|?uW0`yb_=_-h8&=ey^0CHp@$p9^((wj_$F>4@V9ZN+VA2X L#Tf2a84vyduB4_o literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/service/QuizRoomServiceImpl.class b/bin/com/codeboy/mvc/model/service/QuizRoomServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..bf485f03e17e7fc4c4cac52df7ff4bb184865ddc GIT binary patch literal 1135 zcmb7DU2hUW6g@+sz=BZG)@rLR^`r2h8>0_KYLmu~1VS_xZK7|(GQlCcGdRp*>K`-F zMBn{U#=DfS#HGfE-FxTmx#ymH@9eMN-+lmiiv2873=e!AdcN+7u0Hj`vG0ZC2i{1S zvGj%aCX!!{wGKOH=VmwzvPd&*4EUIP0atzRb$1|qo5ecAz5gO(D14gIKj)fZznz@k z<9e=xfDMM7<49Q{aG5(BkcNtRMH+Ytkvo#4C!ao zUlwJC@}h+o#%PnnMTX`(WyDAaW6^U-%}@ptR(EJLl?k7?PJT}A`aCY{c7;37vD)RX zJsk?iK?#?NDBv=~X05#_*0Dyaej^rBZc8OzMPXN%x19JHDsAoa;Dj3)pQpjJ{V1ug zhb!iD&aSBca$nfl7Ta=UsYb1SCMU8o@ZuQ3@*UY%+(w2(JpK!Cu%dL&E>_bxY~*l* zq597eGL(EHxD_*9w3b?{-ef2av{Z{|rq*i3b1Ko56w7ehq5_=?I;il(qR&7d#X zB0t8*{uOMKWw?rKgxVoLh1~?E>j_NdM5dc?m$at<8 literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/service/ScoreService.class b/bin/com/codeboy/mvc/model/service/ScoreService.class new file mode 100644 index 0000000000000000000000000000000000000000..384f9b43cb9b9d45c46f93c19be6b0807494254f GIT binary patch literal 321 zcma)%Jx;?w5Jtao>^PW&{M>*JBE%j5NP|RWk-|~>^)iBuY_GI&EO9I8JRd+_!(pPHBzO#l^VVvjU4^qU0$wqft zRl0dq%W}h}CG_uYW7`FxcXhoc#E-HeLl0*|BpjyCvM@ryJc7vcm1W;U^pRPXFuP22)%@yyRX;rQjo(3aJAF$@~+84;e(rB*Qc0 S!@1<}&?izyLWB#+2;*Pu(n~V{ literal 0 HcmV?d00001 diff --git a/bin/com/codeboy/mvc/model/service/UserProblemService.class b/bin/com/codeboy/mvc/model/service/UserProblemService.class new file mode 100644 index 0000000000000000000000000000000000000000..3f98a1daaf35c86f06e1dd8a4275618651161aae GIT binary patch literal 339 zcmb7Au}%U(6r6Y5ae9If8frVGa1AX;V`6nt5|Dmx-N=&L+hjQ|@w2Q%T zsBGrV%*&fh-r@Ue58xjC6cOQ0IV+TV)rET(wo$?|FU3~-#waabn9RK^N^KXvR*IO= z-^fOaQdV!`x!7n`6WUW#nR-TOUEiz-@dM{%XyLqr1Z_euH> createQuizRoom(@RequestBody CreateQuizRoomRequest request) { + long memberId = request.getMemberId(); + + //1. memberId가 유효한지 체크 + //TODO : membertable에서 해당 멤버가 있는지 확인하는 조건 추가 + if (memberId <= 0) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "멤버ID가 유효하지 않습니다.", null + )); + } + + //2. 새로운 채팅방 생성하기 + long quizRoomId = quizRoomService.createQuizRoom(); + if (quizRoomId <= 0) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "새로운 퀴즈방 생성에 실패했습니다. ", null)); + } + //3. QuizRoomMember 객체 생성 + QuizRoomMember quizRoomMember = new QuizRoomMember(); + //4. setter로 객체 만들기 + quizRoomMember.setMemberId(memberId); + quizRoomMember.setRoomId(quizRoomId); + quizRoomMember.setIsHost(true); + + //5. 채팅방에 넣기 + boolean isOk = quizRoomService.joinQuizRoom(quizRoomMember); + + if (!isOk) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "호스트를 퀴즈방에 넣는 과정이 실패했습니다. ", null)); + } + return ResponseEntity.status(HttpStatus.CREATED).body(new ApiResponse<>(true, "채팅방이 성공적으로 생성되었습니다.", quizRoomId)); + } + + //채팅방 참여하기 + @PostMapping("/join") + //TODO : 로그인 구현되면 memberId를 requestBody로 넘기지 말고 세션에서 가져오도록 하기 + public ResponseEntity> joinQuizRoom(@RequestBody JoinQuizRoomRequest request) { + long memberId = request.getMemberId(); + long roomId = request.getRoomId(); + //TODO : 멤버 ID가 DB에 있는지 확인하는 과정 + if (memberId <= 0) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "멤버ID가 유효하지 않습니다.", null)); + } + //TODO : 채팅방 인원이 초과되었는지 확인하는 메서드 추가 + //퀴즈방 기본 검증 + if (roomId <= 0) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "퀴즈방ID가 유효하지 않습니다.", null)); + } + //퀴즈방이 존재하는지 확인 + boolean roomExists = quizRoomService.existsQuizRoom(roomId); + if (!roomExists) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "존재하지 않는 퀴즈방입니다.", null) + ); + } + //QuizRoomMember 생성 + QuizRoomMember quizRoomMember = new QuizRoomMember(); + quizRoomMember.setIsHost(false); + quizRoomMember.setMemberId(memberId); + quizRoomMember.setRoomId(roomId); + + //채팅방에 넣기 + boolean isOk = quizRoomService.joinQuizRoom(quizRoomMember); + + if (!isOk) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "채팅방 입장에 실패하였습니다. ", null)); + } + return ResponseEntity.status(HttpStatus.CREATED).body(new ApiResponse<>(true, "채팅방 입장에 성공하였습니다.", null)); + } + + //채팅방 목록 보여주기 + @GetMapping + public ResponseEntity>> getQuizRoomList() { + List quizRooms = quizRoomService.getQuizRoomList(); + if (quizRooms == null) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "퀴즈방 정보를 가져오지 못했습니다", null)); + } + else if (quizRooms.isEmpty()) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false,"생성된 퀴즈방이 없습니다.", null)); + } + return ResponseEntity.status(HttpStatus.OK) .body(new ApiResponse<>(true, "퀴즈방 목록 조회 성공", quizRooms)); + } + + + + //현재 참가자 목록 보여주기 + @GetMapping("/{roomId}/member") + public ResponseEntity>> getQuizRoomMembers(@PathVariable long roomId) { + if (roomId <= 0) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "채팅방 ID가 유효하지 않습니다.", null)); + } + + List memberList = quizRoomService.getOneQuizRoomMember(roomId); + + //TODO : member API 와 연결해서 참가 중인 멤버 닉네임을 보여주도록? + if (!memberList.isEmpty()) { + return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(true, "멤버 리스트를 반환합니다.", memberList )); + } + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "참가자가 없습니다.", null)); + + } + + //채팅방 삭제하기 + @DeleteMapping("/{roomId}") + public ResponseEntity> deleteQuizRoom(@PathVariable long roomId) { + if (roomId <= 0) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "채팅방 ID가 유효하지 않습니다.", null)); + } + boolean isOk = quizRoomService.deleteQuizRoom(roomId); + if (!isOk) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "채팅방 삭제에 실패했습니다.", null)); + } + return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(true, "성공적으로 채팅방이 삭제되었습니다. ", null + )); + + + } + +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e38678b --- /dev/null +++ b/pom.xml @@ -0,0 +1,19 @@ + + 4.0.0 + Backend + Backend + 0.0.1-SNAPSHOT + + codeBoy_backend/src/main/java + codeBoy_backend/src/test/java + + + maven-compiler-plugin + 3.8.1 + + 17 + + + + + \ No newline at end of file diff --git a/target/classes/META-INF/MANIFEST.MF b/target/classes/META-INF/MANIFEST.MF new file mode 100644 index 0000000..b55046a --- /dev/null +++ b/target/classes/META-INF/MANIFEST.MF @@ -0,0 +1,4 @@ +Manifest-Version: 1.0 +Build-Jdk-Spec: 17 +Created-By: Maven Integration for Eclipse + diff --git a/target/classes/META-INF/maven/Backend/Backend/pom.properties b/target/classes/META-INF/maven/Backend/Backend/pom.properties new file mode 100644 index 0000000..98c9f29 --- /dev/null +++ b/target/classes/META-INF/maven/Backend/Backend/pom.properties @@ -0,0 +1,7 @@ +#Generated by Maven Integration for Eclipse +#Tue Nov 25 11:26:58 KST 2025 +m2e.projectLocation=C\:\\minseung\\Backend +m2e.projectName=Backend +groupId=Backend +artifactId=Backend +version=0.0.1-SNAPSHOT diff --git a/target/classes/META-INF/maven/Backend/Backend/pom.xml b/target/classes/META-INF/maven/Backend/Backend/pom.xml new file mode 100644 index 0000000..e38678b --- /dev/null +++ b/target/classes/META-INF/maven/Backend/Backend/pom.xml @@ -0,0 +1,19 @@ + + 4.0.0 + Backend + Backend + 0.0.1-SNAPSHOT + + codeBoy_backend/src/main/java + codeBoy_backend/src/test/java + + + maven-compiler-plugin + 3.8.1 + + 17 + + + + + \ No newline at end of file diff --git a/target/classes/com/codeboy/CodeBoyBackendApplication.class b/target/classes/com/codeboy/CodeBoyBackendApplication.class new file mode 100644 index 0000000000000000000000000000000000000000..61bc0a93a30e3540a68e390e01681881d612696b GIT binary patch literal 723 zcma)4%TB{E5FD36ODM1Meh7&JqVzy+Tnb1OiBkj;MdiTB2__g4yK)>JpT!Bpfe+xL z5bJ={9*V?eH#=+3&W`i>_5K0i0P7W$7`7sv`jNgCp?>y{DYx}=n@9ITT_5#&iHx|F zT2)YHn7QK*+)ucQ{j=~+M3!M}Un*%28AcjAU52tF@Gye$8b&e3FdaxGPV+Pr=7NWb zV5kQ=;z^eq>FQswY;R@8upRtMOp6AkTq=ge##PW4)v-pZxV6*uFpIeg>I_Y7Vn6FS z{KoK9JZf|Ahgw^|Q-A|2)-aC+TEyf;95x1cj}x9{tznabVf2w!RyLcFDWz@kaKwK&RApfT z&#fl8g-r2lNt@gmklVs0$QAlyfD(Ptvr?>3Qv|^ga>^Aml^C9G6vB)65>;-6}$9@DP;-&m9mE| z8W*4aqm1WvZ1hF!L+?5FobNl|x##@;^Zg3ID^x^87>c@US9SNJF>ohz+P3Rdo0@M7 zU2h^H%8)tL&a|qfIm4>rjBSSHR_CCrbPih`MS0ii95QUQ7m(B$qUziB8-^vNb8@`h zd)+=!REEtD|3M`hx@9`1zsDey$~~fKlFS5RDUb*WS=?cWH)bjMQhP2`^*z%W)?4LX zl5+1#h#{VU$ep|d5pizamyke`sM@AubjJ3;@ZM_!%V5a0U0t(!nrCu9xJ*I7GD+}1 znbidvT z^>uSajWLLUi0&tbS{OF#y}a;sc{?QuPf%uf5k@yHZ8WNfO5W1Vq`vvxITm*8!xr5!{eEt{BG28?I literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/common/Status.class b/target/classes/com/codeboy/common/Status.class new file mode 100644 index 0000000000000000000000000000000000000000..c5f01afd7f810a15fce7faa700b45eb370ae8cbd GIT binary patch literal 996 zcmaJ$S(8-T(%HQh>TryYeKv#wPKfkm{OMTuasSE z(YSc+k20ROu+f{*i=NNtoaemf{QdXy2EcpNMZ_42hUYX4@3T4drX(H5a~o=)2a~ag zI79Yazt9`D?v5HAcj7Q4kJ_hQt;106-HU88q`Ljv#7w7ucD$_}_0BpfL*>(IT+6U6 z*9s08glbJ=h_{Jb3JD1e>oRh9Kpa|<Q()BxAAZHBb&`})-IzD*gF=m;mnbJGZ#-N;n8E*gtL3@My^VQ55Q zi^*#%UY3timGKHShPP2{+t$b9W~AX=u_bxFdD^L@dK2F;KUn;^GV>#;^DLT3wMH%- zjZcxiNHLCVt)O+#Jlvc7AS`8DAR z*-PX@<54^`HWI%nB+QUk2k{v;)JtssAVdsB`e(y#aja3d66vKd!lQIsiyr&r=bS`k zr*ehz5}c$2q8ftaP#00*WQph#Y%SpLs5FNcX4o8j6qK7mi!(YF%GY?h`<)_lD)VaW jjzXID^LkN3p&Z^z$}{B}Z~lPYkBdPGYwln-lzaaHTgTO3 literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/config/SwaggerConfig.class b/target/classes/com/codeboy/mvc/config/SwaggerConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..995d405f3bf1ab2eabaf890b738bff96bf76e1d1 GIT binary patch literal 1317 zcma)5T~8B16g^W4+m=~D@GAL$F zH)fyAllt&*T$tRhisgj~ZfZ8ql8lVa7pf=<2rlLgM`ZOSVGBw-YZ#`ZIl?q3>uB7x z(%jBj!bq=LT2|jMt>>}|j{d^oS{=$C>Y5Q%aE>ALzmz`s;Z@MXFmNI?W@dAyp&O3v zLpQuKB&gy7E;9J24mBUceE8%SHaMb9)WHXa%POwmDwR;niFsqyq^h4*LO~ENaZ#zS zPenfl=s(MAhDWC;YXmkSOu;pV{u3)z=kj3?UJt_5i;2YS+;XV&>1%m&J4CG@T_Y-P z;3h+>BOKXlQ{i}{WfPA4!Kam}o+j!+gdsM)HZilP+YYh+O;mbyP=3E#-q{S5wmz13 z-W>0L4;}BlEAJeH${)6m_rLslyIb0NP0q+Pr*NriOvSiV)xM(JDNE#J+j%fSGRGt1 zkueFmqheA*l!9*Az4VD6A7*^!3uYktkS8OaR03$Za1iV=xLz2q9G)jK!v=A>;`?HPJfq>E=<*5au4_e&}v(j literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/controller/MemberController.class b/target/classes/com/codeboy/mvc/controller/MemberController.class new file mode 100644 index 0000000000000000000000000000000000000000..172042d32bb536ff73a2a0393d8a0d2dc38ea7a2 GIT binary patch literal 1177 zcmb7D-A+_75T33JyDSKZf`Wf#Ra~Oj3x8rfUjVjETwl`}eugkiHHt_w4@W5_|4K>sptau#tFvM2Rr5jX;!ccqfuS3gc)| zs5GWC4WXP|lEM_J)2#%NaDq%f80Gid5op z>ie7L2uom~q5~c+awEOIWz4!4(h``c9D=1X5@Kbj(uBaR(w@i|$%$CQ=`DK8<9jP4 zFkDTs%~&i-E3uqOrL=3&gw@=vXcID<_-2+2kHv~MFWHKyv$|9b#&>+#oVIS3CyDQx zKu42DDR!D;+vOE^qs(!i%?Yy$?)HJDv5K8qvwQ83Nr6VFM!*|LqBkZMjTU7apvC`bK}f`$#v| z-qVc_YwK^`wjzBPi~3txE_JPR2S&YfR axfTe;9OqG|J3ymQ#M=uNF2W@XV}AhPFHqP3 literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/dao/CommentDao.class b/target/classes/com/codeboy/mvc/model/dao/CommentDao.class new file mode 100644 index 0000000000000000000000000000000000000000..26d5a0eaaf480c04175c6c88788b338619b54f5b GIT binary patch literal 379 zcma)&!Ab)`5Jaovnl;fi0sRD#e_s-gMi1kB?QWxWDz{CX5PCB^uXJo{CY=9vT;zX{ z#4X9>O1{Z#)o>j*aD>y*KZ4_D3AQh#j=T+Kawq@Li7<(+KMQSb_|7`v9DH|h_H|H~ jK-iJ`fJ7?UMOSnxs)IezJ@jQk*x$Sd$Ye)2TssDzFa~EB literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/dao/IncorrectNoteDao.class b/target/classes/com/codeboy/mvc/model/dao/IncorrectNoteDao.class new file mode 100644 index 0000000000000000000000000000000000000000..da97c4b7d147a368c48edec7d8a671db9f7dc557 GIT binary patch literal 348 zcmZ`#%Sr=55Ufs2*2D*bsK1bSaIQkslL#)03IXr4lO{}<-G}e&Q#h5v#?^GYbPJbt?Y`o!_$N{l zv$dW*sLiG3CW^m*IMPe zT&mY(#l{hOSy^-Ce(wmk@$4U%YhmNjyU1$JMc>LM@$86RxGF1`+F~i z#8dyN`AD_n_S1d*e3J6!6?6VVm3!g?3JQ5~bvoq{XUGk#X zIvWYkt@8?(K?1+z*LKQ5YMz_uN@@1lYks!qV&yrn+L#g2RaMp|c8w#f@7sR6$-1f@ t|Egyn8Zlf+*I4&edCeIAA2mCb=@SSK`VWBg#wYYuC#rfFD5Yl_{sLxNTG0Ri literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/dao/QuizRoomDao.class b/target/classes/com/codeboy/mvc/model/dao/QuizRoomDao.class new file mode 100644 index 0000000000000000000000000000000000000000..b99a818ca4052769a7efa3785e17e5a458c6da6f GIT binary patch literal 525 zcma)(-Acni5QWdywy{-Xf5bNsk_+8iA^sqUP>B?+c)v-PvSpKnWK+;b^TG%4p~Okr z8leik+TEGi`R2^|{CfWYaET)a4Th80Bs?}#8JSm}EMlI}UGu3h{IO7PPsSv-!Z>I$ z^yXqAxEAS*kE6MaErYAlTxND%$*|-3BZlK;_(3L-%$`l1KJ~(Xc(&#(zXkpaLqC_A zKsQ>~JqDg1R+AJ~X&$QF1`M5vnx(=PnPfQMD7e^y8eCDE6>pr%nm6=De*mvHquWqc z+Dev7dzSVWsOjC8n!6KIWU;(cnzZ!RbC3yVrRp{VZJ7)NTI5L!ZIs?P*sabEx|H9e XYy literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/dao/ScoreDao.class b/target/classes/com/codeboy/mvc/model/dao/ScoreDao.class new file mode 100644 index 0000000000000000000000000000000000000000..2d9d910b121141924686a3167f38c00a4d4c9c9c GIT binary patch literal 380 zcma)&K}*9x6olv1*x1(E;!p6DTzqG#3W5lQKo3Fh+s#t8Y_gJU3jQ?@{s4cJ_`0YR zMDX_Zn_*^|_m9^%05_PY7!WSBuUY%bto;kuJI%G+jw|K4)V?+M%BM&O^R3z`cBWxgcL`sYf8Lt$L{zSZWzI;ow0&v3c_-H<>ylKp^0 dRyoE{4nm3(;Ul2~jO9JSY2?$rF3MR{W}m~7XP*E7 literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.class b/target/classes/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.class new file mode 100644 index 0000000000000000000000000000000000000000..caf04d0bfc5752611a86bb1ce0e231c36c16ae12 GIT binary patch literal 372 zcmZ`#%T5A85Ud7a0Ut5pB>n(gm=6Fw851`fFd=%M9Xe#l>`pQ}OX9D2@B{oPV=rA)H2@+Nw}}r$#8V?8hq}!s0hPxI?47&b+k@pwu&=Ce`PnNj&)$d{Qt&0 zJ7X>WSv$zj9z|*-o;mWV?+Kl8noizj$(EAnq({PFZ^Z(HEPOp|&+YuXFQyW(mB)>cCMYr8{0{@9&_KP5rmSO7kB{jwK ze)jL9HgLCoNoi%B&AMcx?B#~u!e1~u^5>{rsfe- zXvb{q4eJ@Dg!W}95@;UqIcG7~6Sg-x5RoTP#mw}6XH0-RCs0vBjf73za%8l}D*~c(-`PF&Au=j|-=#vb!w)EmmFKTJeW-8KJ)e zM&hYV%hh{174M`xAh5AN(;lg`qvz5|Y|u@2nr$EJx5MS>V!_pLX@(fBg!!a0GoJ^V z>x%}%W6IwSrD5(ZpG<^h^SjJ&$1+ak{h1PD$yq;|3dONhZ7f`5Ws*`8|LW)a4?jM= zquYZ$=l~KOU+O6+pp?)mKzX4nP|f@RYMHKQaeRlkh%J}8?3hJvU6s3c54W))Tn<&>E-1rR();%Kt literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/dto/IncorrectNote.class b/target/classes/com/codeboy/mvc/model/dto/IncorrectNote.class new file mode 100644 index 0000000000000000000000000000000000000000..f68c8d482436c78763adb678771489475a84fc3c GIT binary patch literal 1045 zcmc&z&2AGh5FRHXKbt_>v;|7}aktzK>1Qz!Al(U4JA=`=e@P$BA{qEI?36Q4*s#@wuy3DMN zosANyGhDu>jPef%6gM^p1WMbOs{&_{<%sx^bJkU%Nr-%IoJ?&pl`+LC$134oSwrW9 z>0KJs`Xfn|9$V*WVs&I+P{EC{o<@@X3jQBnUE6lUblaNLyNU4DolqC`mU8O%$1yNf}Wi?As?%p^pB0Zm6bwZ?b*b5rDexVRjM#qJDYF537Bgs zJl1JsT@H`;6R)e`tZO-(^#mBqYsDn??*lnHr01IF8m?b>R`AZ3w5jSRDumb1ND#C@_>msb8Zb1nypN{}Y z3=e_?65M$fcm>4lZcst31e`dGXT~%0c|897<@<+E0Pp~A)S*IvMnt zLOWqYZ`d=T2Ex{%N??AMk2y=Yj@kBLS45sbLlxo8Ap!D~Kt-a_3J>#o-bx+c!^D(3 zw{I-Q8(KztnkzwIS|~0P0)dmU&e9F;akE|4yH^S8OC_A=Dn*1E8a{Ibmcw7WMOzuo zdPNY^n%KDTVpw9;?n^EGLjqHswH*T0b-Y&{775H9_V~zJV;gXW5b;7=;Y>0X!+avC zOt_au)6|+lB9yyJgPHzFP^nU5Jxz=nm^~VCt&OJxL4OwikE|`zwXs__+IgEr-q>UM zqTWzW{Xr^%nQoH&Tfr0Iz4#Mq?=O-9Xv5MhoPu)%7CT4Dl0Vd3D7Dzia_aRt&OT?A ziFmTZt<3$&X4Q`*GGg^NMjXdqBu3CPnT^C_nWHsJTHnf9fQ)*cX^&Lf)MM!+!guo* zE#4l{7s4a6MYwi&bb`3u2+KJYW;qQsmnH}790Pwdl!m!|9>>D6@oi?fV+Eti^O+Ju z$yqNN;a@>0n{npkrkrQ=}j2Qaxx3;+NC literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/dto/MemberUpdateRequest.class b/target/classes/com/codeboy/mvc/model/dto/MemberUpdateRequest.class new file mode 100644 index 0000000000000000000000000000000000000000..d3baf05d1689d9c1475da0b9c2845f1c53f14e67 GIT binary patch literal 1070 zcmc&zOK%e~5FRIK9-BZ)+CoctxSWav_y8wfQdAy7T2iS=BlYOr9VKpe*NfK)>Ww3R z0Eq*K{0ESbK!Q7eh5QD@>?Wv(MuMI=jA!imX2zcR{NvY`ZvgNJZd9Pa;I^+L;p+fB zeJrA}FCwx-5m+r=V&tLOPXcLi4_}QiwG}8aSU!|vDMA?!#IARUzGYC2m4DQc5i)4G zC+@B_DjqywP*4GbC5)sB8I&KYSlP!6irY8)3`#pxu>$89G*2R*8lz1WnvCIoY%tZ~ z7z0jsO;jkY(lJkr_Ck!(``oGZhR9WvXk&S(BTpZ3U&gVv+(Z5+_yit%~qPJXWcq z!tHF6@<=6w1?`HL6s3TQu3AJwB$ke2B`){ck*|{~-@q?` z#0RiL2m})B`4s3kAm%2Qv?!5)RTtwqW6vCq?c;AhKYam!d$68@83L=q1WcHgY?=WJ z`ho?Beb#b@J+Y?g%OC{_0&{!3&zaA4o9#CDq;Lc>-O>7XivW2{pcuznG89&IoiZ9H zy~Dzqvr4z`5J-uRQ9|Avqg!LNF-DsNl3a)T(h^7u?qu880f80oXv2sDqggdxM(*TY zrIou+V79#8AdslyaZ<2Apm5m818a>g8YvX8B(%;3$k+owgwjEZD4xQ}@XY7=|s56vPH|WZ2rsDhmSMW$W zC;!G;`-h|~l;CV0=3t4yVtG;#(L)tHrR7d9Xi8h>D7#2HMsUBut%~A!GT}NZB(U~} z3Z}{ywUDiuo)z+;isdif+|+VHHsC_^Hz{11BJfXa-UkMLrYzZ0vKf&&U2`>`y@f^YJU= zJI&)*#Ap*)3Ht13C_OJOet<{1) T+8Wwrv@2*ithtJIErjwfao*p7Bp>>1P?IX4pq>?tYtwAKCrgSoXELk86i zf~iA`LFX{>k#p!8FwdBJZk@_7ovMUW0~4J}uhH^}!zfiIyUT;-V63<{6Lg-ZXd-;c zV`(jV9w~m1{6C_$u;)hE2HMQKJof00>5F^hlKZ`h3Yxt%{kMcC%6oMZYX2{S0tlef zhB_=TSY8Vc7t!}l+tGTls7|P@+R9C&+(6Ro8FWL8Wjd5j7y7=j>c=``a6LTvT-F%` zeau~~9_s>c{@{*o6%8<0-N~)jMs3=u&NP+i6PsFf0Guwi7pbgDCZK<b~6~*k#&doP7H}mcHU!T7Mz*RVthYW+dhoSJ$ zS1zuKaNvoM>_GSy#r?j1x{Mg!Q=zL&9(0_pKUY9&Qm9Os4%E(M&C3BO#u!t zrXEB_#TX2f&*>j}I*?Xl#CrzaK!x#TUMjY_itDh4#_|9|7aws?MiE->D*gxjKcW_~ zVLI_VMzJ-0&!X9-FK&@bZdZG%RBQynzX5J5Yt`SfHun%zf(fXNLm8$ROxL%pt!a&p zI&;aQDvplSVm~2COVaEaR2}qW(3VCg_mMMeyEfjd)j~ATv8Hm3WWy;Js9Me0F>6XY-N{bTJpztLKPlR)o)-f0#xun%%%WgtJ&g^?~oiTw25Xg}k0?x))&LNU^%FEH`2 zI{68z-%{)}ow@W&77mh~#8VU;g2SZ8V1~{N9D!NVRjPWF^f8j-BqvBXNtrN7U#DU? F{Tn3dLdF09 literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/dto/UserIncorrectNote.class b/target/classes/com/codeboy/mvc/model/dto/UserIncorrectNote.class new file mode 100644 index 0000000000000000000000000000000000000000..fa5024b4c9225b50213f530e3ca7311a534787a1 GIT binary patch literal 1076 zcmc&zJ8u&~5T3P7{0t6u5(o)oLlwkh3#bSnS>Yk0lY_8hiE{65WpB9Kwf5FV>1b%+ z4^X6VK}n0SK!TpXV)GXeb7!MSI1;3yn4Ov3Z@yX0plVUgg`D7 zp^Gf&F258B+w*q>cyY*$7EZaAlyuN?w~rtTY0Jd!c->f8k0jK4%+{aIgG8H&0Z z$Vg(+THNPkA~0vwnX5Q5FFW&f#p|3itzKeIYlP<7EJ6DO`sS-AxEmBFCx##UOcV@HYP{I$?(01(0#d9Hf$-pw& or6~$lU=_VIoKH{}U=4KzGH?;~I?4vhC6vo3MU2@*p%HBT0_T834gdfE literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/dto/UserProblem.class b/target/classes/com/codeboy/mvc/model/dto/UserProblem.class new file mode 100644 index 0000000000000000000000000000000000000000..3a1e83210c86001368e52bac496f739eddbbb136 GIT binary patch literal 1241 zcmc&!-A)rh6g~sBg;J!JA4NpR9|V**QMmFiAw>;l1I7Z0m(%G}v%ZVUGZ^ih#H=?Mu$K%f?cSa>jFr=E zudSiQ;AC^nJ8hbe7z`=tv1#2tgV~^;2jR#XQO!P6XhF5CR(SsyJvc_o$7qE?UYd9h z9fMMm1C6iRjv=CKo%r{Wt)Wl&<{xXL{Zj^m3yV7pa#cEf0WLBaJE8l`IqQaCnlaoq z4r3d3vB4>QTZb|^9nTINKjg*Xtrl_}wXO3!v{Bu@{snrEe@jYj|7%bYreLN7<8Xz+2xyB7IVI(V+QlTiR+IdCz%y%w&N5&*GbB9-vhXp=z+n^Yf_Vr zaNTrutf|mya<{1psLn)iy33SwJUG?MMEpUoV=3(Qh2V5nVCRhVOM$i`-jmHHI?-Jg zR>mULRsTM|(QjIkFA7J_D;PB}1-S_t&j}8y`+SVpq2a-Mg35qZP=O9mL z017aa`e9m4<|Em>l=;!jpU?bQ=F4y)jjyD6=(*ALP0%<=t1DE6kuQFRsW+8NAK>!W zG~@BS;se?fe^sg%+}^(4!i_p!hC!Tb3B>+@FtcnE7Hm?O{%wPK-;M40nlgy-&SL zw=bwv18p2lv^=wdeU#4Pfn2oW^aSI4Ed>!(n$BoSN zLu0}9r6q97|JzMkC*XDT(1hZt%%V1rFWQ}~7y>IVhpCfFY^Eb=C8ld<6V7)5vo-w_ zy~ePM{>hG_x$MvSmW#9QptyXPpm$36+rHGyzUFZ(3>)2Lnp>7{*epL&B9feS!oE-( zLscVTLn8;-q7qo09*n2sH`DRK^uzlfA19gccJlMxgg)+W!y4cr-~rCzcMgiVRLVIX z4i2P(uZPxqh$6_nFHqfWoc{#%Z#lMsZ!!NgX$zF{@1a8$}j=}BJYLVIu6MHE1 zG!>fcTx7wDeUGl6T8A~LFjzW}Qz>$3hGI84z%($ZYt#w4UdDjEVzA%~Fxfo@)yK-H z@RY&)=G_5<$~Ljq-~xm83C(lotgAztG2Ax}z0IeXamr_`av790eC%wJqxO$@)Yuy# zS9)w+;JMX_ealm6j14?N{@eL~pmuE64gIz?KDbF5tUDtw9xRtU9F8$+bo2b*9A07w z_&3)6IY1G#;9?6J&|$E;8J{$wADlA7t)fxwSQ*@z6m8v;RC@-U*rqZcNT-VZ@nI#5 zlxJ`!KF9QIF^Kwh;!=E}3c|%db9KK+fx-Igi3v($&rFq96r@}9wVVKou^gYOFfp#g zr|U?^^>|jT(wxA#LXeK>mmkw4qpg$DqN!7JX|hOS742F2P$xt^g78klItWlNSfqxlZ1QN_yy7< BAwmEE literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/service/CommentService.class b/target/classes/com/codeboy/mvc/model/service/CommentService.class new file mode 100644 index 0000000000000000000000000000000000000000..d44b062071fd50526967d8db9af0e76ff4d363a7 GIT binary patch literal 327 zcmb7e2I3}HLn;L)$y7)k8A$Fwaq%I82$^Jf UhJ3h^>>c|=YF~(OEg4~O0JO|az5oCK literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/service/IncorrectNoteService.class b/target/classes/com/codeboy/mvc/model/service/IncorrectNoteService.class new file mode 100644 index 0000000000000000000000000000000000000000..eea54f05f9adda47609f4f9ddc26044b7c9de7fa GIT binary patch literal 345 zcmb7=KT88a5XIkI?s9sGCfHfpX^Jd}oqrlZ5RRmXq~BWy-Eemco6CV8D^Hmtx8>gsA;i~1w!}1*0y;fbgpmag!ox5W$56vj|5%9Ah$J7R#n0NO&28- zE^=pdIoI9>e+c8|(=G{j`SE1;gly(k-tdbJ_b>m$9|v+=K{(|fAe922Xev(aJdlhw cI9W>&ArlQ_$b+6}f7d5c&%_bVMI#LU05@?}6aWAK literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/service/MemberService.class b/target/classes/com/codeboy/mvc/model/service/MemberService.class new file mode 100644 index 0000000000000000000000000000000000000000..0d73745679abe03ce5252befb76b8de6438d3707 GIT binary patch literal 367 zcmah_%SyvQ6g{`bMr(ZFSELBe!ewwPDlLLR_mi1RoRVbfWRl{qx$p!0C~=xvL=@cI z7x$iX?s@-seFJcb;}|2tnXvZ;gmV0NKGW$K5&i)poz5NoB1>BYKPuj_q ztO!whv*t>=rIwzzY!~V6zeo?m#XUcF-1=+~oZHSRzA_aPPJcXpz7{_wgx`X7Kooq~ Z#W)m%7<)tB$7IL{NWuo;FvJm#J^_jsb_ofTC7q(Hta$kzA_Ki_mEW9g9ZI{0`MNAlO zWFti>t9LOkHd@t$_RLhKej>EScWXlY%o!P4=yZ{wO&H{+(yu#PXup!2M;PT!$#N~d z3I1;w*B@p}nC6!-JrJ^`+j*s5Oh~@@k30>uxCOKE*WgNli8W;>&K^ka54if|L4=Go UticD@tle{;aP6@p^jRYePO-yHxBvhE literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/service/QuizRoomService.class b/target/classes/com/codeboy/mvc/model/service/QuizRoomService.class new file mode 100644 index 0000000000000000000000000000000000000000..11f4bb1a533675bb422b1020a120c821fa2484fa GIT binary patch literal 639 zcmZuvO>Yx15Pfc&uO%dHNcje>dfHTN_lij9g%62n0l`A0a&sIjIP%(+>sZ9)!kvHjkRpJ(3q*Y9sX06f9N2DTWEg)LHHr*dL1(_$&og3dZ!NVil%rf*C2 z<(;)feuW#@Vc4DXB~LXsv-HhmE`?`kj)Yc5`BR4NWN^l?^OR&7Xfbp*+0UJ`u8C_5 z=O2ud3#*rM8dCumN^`HQi7%X;XjwdtqgH-tJpUZaaOWsihAQ&$!SEpVwz{IFm+>p< zKiTOsDKvMLLKLBi>uq$+|)fi8L8+8Vn7JUVv zMyAzJC)^-(xMHL4XrA|?uW0`yb_=_-h8&=ey^0CHp@$p9^((wj_$F>4@V9ZN+VA2X L#Tf2a84vyduB4_o literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/service/QuizRoomServiceImpl.class b/target/classes/com/codeboy/mvc/model/service/QuizRoomServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..fc89017dfc7b8529e6e2ed6add25570fec7766b8 GIT binary patch literal 1035 zcmb7C+invv5FKxBZ5oo<R|BR22yVEQEwAwG>q#q(m!F8Hd)wkvuW>6Yol)V}2w8 zXY45#(*nMqICG+`>>+J_S83(;7-Z^=4uk9~w4w+ZsFYv{N(?H#((-K*b)|hTP?y1q zZvqi^gjIAOC$sLO!bYB5GR{A&#U3hs=_aQ8Dt4$*Z}_R(iBln`9Ksgcs;`AhEH<%y z4zPQPbkEJ4+}T5#a$u!!aw3Q`*ISJygM~=al+7Lk)?!c^7^P>RT)ovIgNl>qBU~B3 zjhv@K6F(rPZ4w*EH;U|9pK#25rzbQUYyi5BD~HR20xV!$#BZ9%Sj0$qd;{FC;EiKs zlzsRE%HQ$e!7}ay283V5ouE{<0;?DqT!ZU~TEnvkH&T*Em?ezIzNOh2!|EJ^H)U9d zD&k50ImQgtWWJuMtfrM~s6jd-Z93hATdCS@xHIN>iHIC7cDDUmN>NJ%@bT03X@C(0 bo$ewTd36tJW3uTe=Nj6&aFmU-z59OwxWnNv literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/service/ScoreService.class b/target/classes/com/codeboy/mvc/model/service/ScoreService.class new file mode 100644 index 0000000000000000000000000000000000000000..384f9b43cb9b9d45c46f93c19be6b0807494254f GIT binary patch literal 321 zcma)%Jx;?w5Jtao>^PW&{M>*JBE%j5NP|RWk-|~>^)iBuY_GI&EO9I8JRd+_!(pPHBzO#l^VVvjU4^qU0$wqft zRl0dq%W}h}CG_uYW7`FxcXhoc#E-HeLl0*|BpjyCvM@ryJc7vcm1W;U^pRPXFuP22)%@yyRX;rQjo(3aJAF$@~+84;e(rB*Qc0 S!@1<}&?izyLWB#+2;*Pu(n~V{ literal 0 HcmV?d00001 diff --git a/target/classes/com/codeboy/mvc/model/service/UserProblemService.class b/target/classes/com/codeboy/mvc/model/service/UserProblemService.class new file mode 100644 index 0000000000000000000000000000000000000000..3f98a1daaf35c86f06e1dd8a4275618651161aae GIT binary patch literal 339 zcmb7Au}%U(6r6Y5ae9If8frVGa1AX;V`6nt5|Dmx-N=&L+hjQ|@w2Q%T zsBGrV%*&fh-r@Ue58xjC6cOQ0IV+TV)rET(wo$?|FU3~-#waabn9RK^N^KXvR*IO= z-^fOaQdV!`x!7n`6WUW#nR-TOUEiz-@dM{%XyLqr1Z_euHW8Qdp1}kXWD~ys>bRS|p|jBwBTMTvOa8c9b|kABzczfd}BB z5XS)_#DExlj?cxPkAJ_tzq|rC!)6@;Lr>a-OFL1KUGNL?1G^XqIag-VPt#aS;j}d) zmAkx-Dnn-`?gfv9neyvsrle!2oob`qIYVV{f6P$zlm;qTX<-R9hIXipx+;=LWg`*A zilG}?DdMrnw2!}%Rd=UzhQsjx6P+-$q%}@Gy3mRVo!+`BjMIr4>s%AMZ;W;23#hgo z+HA^a1r19!)lOwxq?-H35veh>MJCmy_7m>@Eya;nf#J9$=4qzQ^fnWTda&7?N7g#- z2uiw^v+-fsF`#^T7j{5m(I)@_EfR_1I_)@l<}1I)Ec1sjoAP`0LsCG*Z=?k literal 0 HcmV?d00001 From b37528c420b4701e15d7724f4c67e27c88c2103b Mon Sep 17 00:00:00 2001 From: mingeung Date: Wed, 26 Nov 2025 14:39:52 +0900 Subject: [PATCH 09/61] =?UTF-8?q?feat=20:=20=ED=80=B4=EC=A6=88=EB=B0=A9=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20api=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20(sql=EB=AC=B8=EC=97=90=20CASCADE=20?= =?UTF-8?q?=EC=86=8D=EC=84=B1=20=EC=B6=94=EA=B0=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/codeboy/mvc/controller/QuizRoomController.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java index 5b9130e..143d1cc 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java @@ -140,8 +140,6 @@ public ResponseEntity> deleteQuizRoom(@PathVariable long roo } return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(true, "성공적으로 채팅방이 삭제되었습니다. ", null )); - - } } From 1062ff0ccbbf245cd0c0f894822c8130c2f1d967 Mon Sep 17 00:00:00 2001 From: mingeung Date: Wed, 26 Nov 2025 16:46:56 +0900 Subject: [PATCH 10/61] =?UTF-8?q?refactor=20:=20dto,=20responseDto,=20requ?= =?UTF-8?q?estDto=20=ED=8F=B4=EB=8D=94=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mvc/controller/ProblemController.java | 51 +++++++++++++++++++ .../mvc/controller/QuizRoomController.java | 19 ++++--- .../com/codeboy/mvc/model/dao/MemberDao.java | 2 +- .../com/codeboy/mvc/model/dao/ProblemDao.java | 6 ++- .../CreateQuizRoomRequest.java | 3 +- .../model/requestDto/GetProblemsRequest.java | 14 +++++ .../JoinQuizRoomRequest.java | 2 +- .../MemberUpdateRequest.java | 2 +- .../{dto => responseDto}/ApiResponse.java | 2 +- .../mvc/model/service/MemberService.java | 2 +- .../mvc/model/service/ProblemService.java | 11 +++- .../mvc/model/service/ProblemServiceImpl.java | 20 ++++++++ .../main/resources/mappers/ProblemMapper.xml | 7 +++ 13 files changed, 123 insertions(+), 18 deletions(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java rename codeBoy_backend/src/main/java/com/codeboy/mvc/model/{dto => requestDto}/CreateQuizRoomRequest.java (78%) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/GetProblemsRequest.java rename codeBoy_backend/src/main/java/com/codeboy/mvc/model/{dto => requestDto}/JoinQuizRoomRequest.java (80%) rename codeBoy_backend/src/main/java/com/codeboy/mvc/model/{dto => requestDto}/MemberUpdateRequest.java (90%) rename codeBoy_backend/src/main/java/com/codeboy/mvc/model/{dto => responseDto}/ApiResponse.java (86%) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java new file mode 100644 index 0000000..78e601a --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java @@ -0,0 +1,51 @@ +package com.codeboy.mvc.controller; + +import com.codeboy.common.Category; +import com.codeboy.mvc.model.responseDto.ApiResponse; +import com.codeboy.mvc.model.requestDto.GetProblemsRequest; +import com.codeboy.mvc.model.dto.Problem; +import com.codeboy.mvc.model.service.ProblemServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("/api/problem") +public class ProblemController { + + @Autowired + private ProblemServiceImpl problemService; + + @GetMapping + public ResponseEntity>> getProblems(@RequestBody GetProblemsRequest request ) { + int limit = request.getLimit(); + Category category = request.getCategory(); + + if (limit <= 0) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "유효하지 않은 limit 입니다", null + )); + } + if (category == null) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "유효하지 않은 category 입니다.",null + )); + } + + List problems = problemService.getProblems(limit, category); + + //만약 요청 수보다 존재하는 문제 수가 적다면 + if (limit > problems.size()) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "요청보다 존재하는 문제 수가 적습니다.", null)); + } + + if (problems.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "해당되는 문제가 존재하지 않습니다. ", null)); + } + return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(true, "문제가 성공적으로 반환되었습니다.", problems)); + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java index 143d1cc..9c147ef 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java @@ -1,5 +1,8 @@ package com.codeboy.mvc.controller; import com.codeboy.mvc.model.dto.*; +import com.codeboy.mvc.model.requestDto.CreateQuizRoomRequest; +import com.codeboy.mvc.model.requestDto.JoinQuizRoomRequest; +import com.codeboy.mvc.model.responseDto.ApiResponse; import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -19,7 +22,7 @@ public class QuizRoomController { private DataSource dataSource; @Autowired - QuizRoomServiceImpl quizRoomService; + private QuizRoomServiceImpl quizRoomService; @PostConstruct public void testConnection() throws SQLException { @@ -57,7 +60,7 @@ public ResponseEntity> createQuizRoom(@RequestBody CreateQuizR if (!isOk) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "호스트를 퀴즈방에 넣는 과정이 실패했습니다. ", null)); } - return ResponseEntity.status(HttpStatus.CREATED).body(new ApiResponse<>(true, "채팅방이 성공적으로 생성되었습니다.", quizRoomId)); + return ResponseEntity.status(HttpStatus.CREATED).body(new ApiResponse<>(true, "퀴즈방이 성공적으로 생성되었습니다.", quizRoomId)); } //채팅방 참여하기 @@ -91,9 +94,9 @@ public ResponseEntity> joinQuizRoom(@RequestBody JoinQuizRoo boolean isOk = quizRoomService.joinQuizRoom(quizRoomMember); if (!isOk) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "채팅방 입장에 실패하였습니다. ", null)); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "퀴즈방 입장에 실패하였습니다. ", null)); } - return ResponseEntity.status(HttpStatus.CREATED).body(new ApiResponse<>(true, "채팅방 입장에 성공하였습니다.", null)); + return ResponseEntity.status(HttpStatus.CREATED).body(new ApiResponse<>(true, "퀴즈방 입장에 성공하였습니다.", null)); } //채팅방 목록 보여주기 @@ -115,7 +118,7 @@ else if (quizRooms.isEmpty()) { @GetMapping("/{roomId}/member") public ResponseEntity>> getQuizRoomMembers(@PathVariable long roomId) { if (roomId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "채팅방 ID가 유효하지 않습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "퀴즈방 ID가 유효하지 않습니다.", null)); } List memberList = quizRoomService.getOneQuizRoomMember(roomId); @@ -132,13 +135,13 @@ public ResponseEntity>> getQuizRoomMembers(@Pat @DeleteMapping("/{roomId}") public ResponseEntity> deleteQuizRoom(@PathVariable long roomId) { if (roomId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "채팅방 ID가 유효하지 않습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "퀴즈방 ID가 유효하지 않습니다.", null)); } boolean isOk = quizRoomService.deleteQuizRoom(roomId); if (!isOk) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "채팅방 삭제에 실패했습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "퀴즈방 삭제에 실패했습니다.", null)); } - return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(true, "성공적으로 채팅방이 삭제되었습니다. ", null + return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(true, "성공적으로 퀴즈방이 삭제되었습니다. ", null )); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java index 2b45cfe..8b7c729 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java @@ -1,7 +1,7 @@ package com.codeboy.mvc.model.dao; import com.codeboy.mvc.model.dto.Member; -import com.codeboy.mvc.model.dto.MemberUpdateRequest; +import com.codeboy.mvc.model.requestDto.MemberUpdateRequest; public interface MemberDao { public void insertMember(Member member); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ProblemDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ProblemDao.java index 04d938e..8cbad50 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ProblemDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ProblemDao.java @@ -4,9 +4,11 @@ import com.codeboy.common.Category; import com.codeboy.mvc.model.dto.Problem; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +@Mapper public interface ProblemDao { //문제 조회 - public List selectProblem(Category category); - + public List selectProblem(@Param("limit") int limit, @Param("category") Category category); } \ No newline at end of file diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CreateQuizRoomRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CreateQuizRoomRequest.java similarity index 78% rename from codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CreateQuizRoomRequest.java rename to codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CreateQuizRoomRequest.java index 0c1d44d..28c816f 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CreateQuizRoomRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CreateQuizRoomRequest.java @@ -1,4 +1,4 @@ -package com.codeboy.mvc.model.dto; +package com.codeboy.mvc.model.requestDto; import lombok.*; @@ -9,5 +9,4 @@ @ToString public class CreateQuizRoomRequest { private long memberId; - } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/GetProblemsRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/GetProblemsRequest.java new file mode 100644 index 0000000..7b2b471 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/GetProblemsRequest.java @@ -0,0 +1,14 @@ +package com.codeboy.mvc.model.requestDto; + +import com.codeboy.common.Category; +import lombok.*; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class GetProblemsRequest { + private int limit; + private Category category; +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/JoinQuizRoomRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/JoinQuizRoomRequest.java similarity index 80% rename from codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/JoinQuizRoomRequest.java rename to codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/JoinQuizRoomRequest.java index 4b8b913..ba0602a 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/JoinQuizRoomRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/JoinQuizRoomRequest.java @@ -1,4 +1,4 @@ -package com.codeboy.mvc.model.dto; +package com.codeboy.mvc.model.requestDto; import lombok.*; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/MemberUpdateRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/MemberUpdateRequest.java similarity index 90% rename from codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/MemberUpdateRequest.java rename to codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/MemberUpdateRequest.java index eb94e12..d742835 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/MemberUpdateRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/MemberUpdateRequest.java @@ -1,4 +1,4 @@ -package com.codeboy.mvc.model.dto; +package com.codeboy.mvc.model.requestDto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/ApiResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java similarity index 86% rename from codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/ApiResponse.java rename to codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java index ca89685..eac7fd1 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/ApiResponse.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java @@ -1,4 +1,4 @@ -package com.codeboy.mvc.model.dto; +package com.codeboy.mvc.model.responseDto; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java index 7a890e3..3fa2195 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java @@ -1,7 +1,7 @@ package com.codeboy.mvc.model.service; import com.codeboy.mvc.model.dto.Member; -import com.codeboy.mvc.model.dto.MemberUpdateRequest; +import com.codeboy.mvc.model.requestDto.MemberUpdateRequest; public interface MemberService { //회원가입 diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemService.java index 959188b..bd2fd88 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemService.java @@ -1,5 +1,14 @@ package com.codeboy.mvc.model.service; -public class ProblemService { +import com.codeboy.common.Category; +import com.codeboy.mvc.model.dto.Problem; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public interface ProblemService { + + public List getProblems(int limit, Category category); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java new file mode 100644 index 0000000..1750269 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java @@ -0,0 +1,20 @@ +package com.codeboy.mvc.model.service; + +import com.codeboy.common.Category; +import com.codeboy.mvc.model.dao.ProblemDao; +import com.codeboy.mvc.model.dto.Problem; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class ProblemServiceImpl implements ProblemService{ + @Autowired + private ProblemDao problemDao; + + @Override + public List getProblems(int limit, Category category) { + return problemDao.selectProblem(limit,category); + } +} diff --git a/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml b/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml index fc40b51..c48de03 100644 --- a/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml @@ -4,5 +4,12 @@ "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> + \ No newline at end of file From 8b173b72136de7e464e8eea174a52bdfb7ddbbd4 Mon Sep 17 00:00:00 2001 From: mingeung Date: Wed, 26 Nov 2025 17:17:00 +0900 Subject: [PATCH 11/61] =?UTF-8?q?feat:=20getProblems=20API=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84,=20limit=EA=B3=BC=20category=EB=A5=BC=20RequestParam?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=A0=84=EB=8B=AC=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mvc/controller/ProblemController.java | 22 ++++-------- .../mvc/controller/QuizRoomController.java | 36 +++++++++---------- .../model/requestDto/GetProblemsRequest.java | 14 -------- .../mvc/model/responseDto/ApiResponse.java | 3 +- 4 files changed, 26 insertions(+), 49 deletions(-) delete mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/GetProblemsRequest.java diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java index 78e601a..cdc9698 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java @@ -2,16 +2,12 @@ import com.codeboy.common.Category; import com.codeboy.mvc.model.responseDto.ApiResponse; -import com.codeboy.mvc.model.requestDto.GetProblemsRequest; import com.codeboy.mvc.model.dto.Problem; import com.codeboy.mvc.model.service.ProblemServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; @@ -23,16 +19,13 @@ public class ProblemController { private ProblemServiceImpl problemService; @GetMapping - public ResponseEntity>> getProblems(@RequestBody GetProblemsRequest request ) { - int limit = request.getLimit(); - Category category = request.getCategory(); - + public ResponseEntity>> getProblems(@RequestParam int limit, @RequestParam Category category) { if (limit <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "유효하지 않은 limit 입니다", null + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "유효하지 않은 limit 입니다", null )); } if (category == null) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "유효하지 않은 category 입니다.",null + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "유효하지 않은 category 입니다.",null )); } @@ -40,12 +33,9 @@ public ResponseEntity>> getProblems(@RequestBody GetPr //만약 요청 수보다 존재하는 문제 수가 적다면 if (limit > problems.size()) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "요청보다 존재하는 문제 수가 적습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "요청보다 존재하는 문제 수가 적습니다.", null)); } - if (problems.isEmpty()) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "해당되는 문제가 존재하지 않습니다. ", null)); - } - return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(true, "문제가 성공적으로 반환되었습니다.", problems)); + return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(HttpStatus.OK, "문제가 성공적으로 반환되었습니다.", problems)); } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java index 9c147ef..659c2e2 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java @@ -38,14 +38,14 @@ public ResponseEntity> createQuizRoom(@RequestBody CreateQuizR //1. memberId가 유효한지 체크 //TODO : membertable에서 해당 멤버가 있는지 확인하는 조건 추가 if (memberId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "멤버ID가 유효하지 않습니다.", null + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "멤버ID가 유효하지 않습니다.", null )); } //2. 새로운 채팅방 생성하기 long quizRoomId = quizRoomService.createQuizRoom(); if (quizRoomId <= 0) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "새로운 퀴즈방 생성에 실패했습니다. ", null)); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "새로운 퀴즈방 생성에 실패했습니다. ", null)); } //3. QuizRoomMember 객체 생성 QuizRoomMember quizRoomMember = new QuizRoomMember(); @@ -58,9 +58,9 @@ public ResponseEntity> createQuizRoom(@RequestBody CreateQuizR boolean isOk = quizRoomService.joinQuizRoom(quizRoomMember); if (!isOk) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "호스트를 퀴즈방에 넣는 과정이 실패했습니다. ", null)); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "호스트를 퀴즈방에 넣는 과정이 실패했습니다. ", null)); } - return ResponseEntity.status(HttpStatus.CREATED).body(new ApiResponse<>(true, "퀴즈방이 성공적으로 생성되었습니다.", quizRoomId)); + return ResponseEntity.status(HttpStatus.CREATED).body(new ApiResponse<>(HttpStatus.CREATED, "퀴즈방이 성공적으로 생성되었습니다.", quizRoomId)); } //채팅방 참여하기 @@ -71,17 +71,17 @@ public ResponseEntity> joinQuizRoom(@RequestBody JoinQuizRoo long roomId = request.getRoomId(); //TODO : 멤버 ID가 DB에 있는지 확인하는 과정 if (memberId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "멤버ID가 유효하지 않습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "멤버ID가 유효하지 않습니다.", null)); } //TODO : 채팅방 인원이 초과되었는지 확인하는 메서드 추가 //퀴즈방 기본 검증 if (roomId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "퀴즈방ID가 유효하지 않습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "퀴즈방ID가 유효하지 않습니다.", null)); } //퀴즈방이 존재하는지 확인 boolean roomExists = quizRoomService.existsQuizRoom(roomId); if (!roomExists) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "존재하지 않는 퀴즈방입니다.", null) + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "존재하지 않는 퀴즈방입니다.", null) ); } //QuizRoomMember 생성 @@ -94,9 +94,9 @@ public ResponseEntity> joinQuizRoom(@RequestBody JoinQuizRoo boolean isOk = quizRoomService.joinQuizRoom(quizRoomMember); if (!isOk) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "퀴즈방 입장에 실패하였습니다. ", null)); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "퀴즈방 입장에 실패하였습니다. ", null)); } - return ResponseEntity.status(HttpStatus.CREATED).body(new ApiResponse<>(true, "퀴즈방 입장에 성공하였습니다.", null)); + return ResponseEntity.status(HttpStatus.CREATED).body(new ApiResponse<>(HttpStatus.CREATED, "퀴즈방 입장에 성공하였습니다.", null)); } //채팅방 목록 보여주기 @@ -104,12 +104,12 @@ public ResponseEntity> joinQuizRoom(@RequestBody JoinQuizRoo public ResponseEntity>> getQuizRoomList() { List quizRooms = quizRoomService.getQuizRoomList(); if (quizRooms == null) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "퀴즈방 정보를 가져오지 못했습니다", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "퀴즈방 정보를 가져오지 못했습니다", null)); } else if (quizRooms.isEmpty()) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false,"생성된 퀴즈방이 없습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST,"생성된 퀴즈방이 없습니다.", null)); } - return ResponseEntity.status(HttpStatus.OK) .body(new ApiResponse<>(true, "퀴즈방 목록 조회 성공", quizRooms)); + return ResponseEntity.status(HttpStatus.OK) .body(new ApiResponse<>(HttpStatus.OK, "퀴즈방 목록 조회 성공", quizRooms)); } @@ -118,16 +118,16 @@ else if (quizRooms.isEmpty()) { @GetMapping("/{roomId}/member") public ResponseEntity>> getQuizRoomMembers(@PathVariable long roomId) { if (roomId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "퀴즈방 ID가 유효하지 않습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "퀴즈방 ID가 유효하지 않습니다.", null)); } List memberList = quizRoomService.getOneQuizRoomMember(roomId); //TODO : member API 와 연결해서 참가 중인 멤버 닉네임을 보여주도록? if (!memberList.isEmpty()) { - return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(true, "멤버 리스트를 반환합니다.", memberList )); + return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(HttpStatus.OK, "멤버 리스트를 반환합니다.", memberList )); } - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(false, "참가자가 없습니다.", null)); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "참가자가 없습니다.", null)); } @@ -135,13 +135,13 @@ public ResponseEntity>> getQuizRoomMembers(@Pat @DeleteMapping("/{roomId}") public ResponseEntity> deleteQuizRoom(@PathVariable long roomId) { if (roomId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "퀴즈방 ID가 유효하지 않습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "퀴즈방 ID가 유효하지 않습니다.", null)); } boolean isOk = quizRoomService.deleteQuizRoom(roomId); if (!isOk) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(false, "퀴즈방 삭제에 실패했습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "퀴즈방 삭제에 실패했습니다.", null)); } - return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(true, "성공적으로 퀴즈방이 삭제되었습니다. ", null + return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(HttpStatus.OK, "성공적으로 퀴즈방이 삭제되었습니다. ", null )); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/GetProblemsRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/GetProblemsRequest.java deleted file mode 100644 index 7b2b471..0000000 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/GetProblemsRequest.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.codeboy.mvc.model.requestDto; - -import com.codeboy.common.Category; -import lombok.*; - -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -@ToString -public class GetProblemsRequest { - private int limit; - private Category category; -} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java index eac7fd1..83718ae 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java @@ -3,12 +3,13 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.springframework.http.HttpStatus; @Data @AllArgsConstructor @NoArgsConstructor public class ApiResponse { - private boolean success; + private HttpStatus status; private String message; private T data; From b82799dad39fe1c56ca420b3811306660f59a7bc Mon Sep 17 00:00:00 2001 From: mingeung Date: Wed, 26 Nov 2025 17:59:40 +0900 Subject: [PATCH 12/61] =?UTF-8?q?feat:=20=EC=98=A4=EB=8B=B5=EB=85=B8?= =?UTF-8?q?=ED=8A=B8=20=ED=8C=8C=EC=9D=BC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/IncorrectNoteController.java | 4 ++++ .../mvc/model/dao/IncorrectNoteDao.java | 2 ++ .../model/service/IncorrectNoteService.java | 2 +- .../service/IncorrectNoteServiceImpl.java | 4 ++++ .../resources/mappers/IncorrectNoteMapper.xml | 19 +++++++++++++++++++ 5 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java create mode 100644 codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java new file mode 100644 index 0000000..19a3e9d --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java @@ -0,0 +1,4 @@ +package com.codeboy.mvc.controller; + +public class IncorrectNoteController { +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java index 929c13c..ce9f08b 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java @@ -15,3 +15,5 @@ public interface IncorrectNoteDao { //오답노트에 문제 추가 public void insertIncorrectProblem(long memberId, long problemId); } + + diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java index e8d653a..c784d5a 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java @@ -1,5 +1,5 @@ package com.codeboy.mvc.model.service; -public class IncorrectNoteService { +public interface IncorrectNoteService { } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java new file mode 100644 index 0000000..0d6f710 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java @@ -0,0 +1,4 @@ +package com.codeboy.mvc.model.service; + +public class IncorrectNoteServiceImpl implements IncorrectNoteService{ +} diff --git a/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml b/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml new file mode 100644 index 0000000..8dc9122 --- /dev/null +++ b/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml @@ -0,0 +1,19 @@ + + + + + + + + DELETE FROM incorrect_note + WHERE + + + + \ No newline at end of file From 2864f17eb736edc2d198e652cb2827af07bb3d5a Mon Sep 17 00:00:00 2001 From: mingeung Date: Thu, 27 Nov 2025 08:43:54 +0900 Subject: [PATCH 13/61] =?UTF-8?q?feat:=20IncorrectNote=20dto.=20=EC=88=98?= =?UTF-8?q?=EC=A0=95.=20ProblemType=20enum=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/codeboy/common/ProblemType.java | 6 ++++++ .../main/java/com/codeboy/mvc/model/dto/IncorrectNote.java | 3 +++ 2 files changed, 9 insertions(+) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/common/ProblemType.java diff --git a/codeBoy_backend/src/main/java/com/codeboy/common/ProblemType.java b/codeBoy_backend/src/main/java/com/codeboy/common/ProblemType.java new file mode 100644 index 0000000..80bdc40 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/common/ProblemType.java @@ -0,0 +1,6 @@ +package com.codeboy.common; + +public enum ProblemType { + PROBLEM, + USERPROBLEM, +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/IncorrectNote.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/IncorrectNote.java index f5d7ed0..477c233 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/IncorrectNote.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/IncorrectNote.java @@ -1,5 +1,6 @@ package com.codeboy.mvc.model.dto; +import com.codeboy.common.ProblemType; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Getter; @@ -15,4 +16,6 @@ public class IncorrectNote { private long incorrectNoteId; private long memberId; private long problemId; + private long userProblemId; + private ProblemType ProblemType; } From 04bca6386a0913d570cf60033fcdfeb8f8b65bc7 Mon Sep 17 00:00:00 2001 From: mingeung Date: Thu, 27 Nov 2025 08:58:08 +0900 Subject: [PATCH 14/61] =?UTF-8?q?feat:=20IncorrectNoteMapper=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/codeboy/mvc/model/dao/IncorrectNoteDao.java | 5 +++-- .../main/resources/mappers/IncorrectNoteMapper.xml | 11 +++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java index ce9f08b..938eab0 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java @@ -2,6 +2,7 @@ import java.util.List; +import com.codeboy.common.ProblemType; import com.codeboy.mvc.model.dto.Problem; public interface IncorrectNoteDao { @@ -10,10 +11,10 @@ public interface IncorrectNoteDao { public List selectIncorrectProblems(long memberId); //유저가 자신의 오답노트 안에서 문제를 삭제 - public void deleteIncorrectProblem(long memberId, long problemId); + public void deleteIncorrectProblem(long memberId, long incorrectNoteId); //오답노트에 문제 추가 - public void insertIncorrectProblem(long memberId, long problemId); + public void insertIncorrectProblem(long memberId, long problemId, long userProblemId, ProblemType problemType); } diff --git a/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml b/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml index 8dc9122..e69cd46 100644 --- a/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml @@ -12,8 +12,15 @@ DELETE FROM incorrect_note - WHERE - + WHERE incorrect_note_id = #{incorrectNoteId} + + + INSERT INTO incorrect_note (member_id, problem_id, user_problem_id, problem_type) + VALUES (#{memberId}, #{problemId}, #{userProblemId}, #{problemType}) + + + + \ No newline at end of file From 369e99fff1600bd6567b624aa301d4d9edc6a837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=A4=80=ED=98=95?= Date: Thu, 27 Nov 2025 10:53:41 +0900 Subject: [PATCH 15/61] =?UTF-8?q?=E2=9C=A8=20CommentUpdateRequest=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EA=B3=BC=20Comment=EC=BB=A8=ED=8A=B8?= =?UTF-8?q?=EB=A1=A4=EB=9F=AC=EC=97=90=20=EC=A0=81=EC=9A=A9.=20Member,=20C?= =?UTF-8?q?omment=20Controller=EC=9D=98=20=EC=88=98=EC=A0=95=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20PutMapping=20->=20PathchMapping=EC=9C=BC=EB=A1=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../codeboy/mvc/model/requestDto/CommentUpdateRequest.java | 4 ++++ .../codeboy/mvc/model/{dto => requestDto}/LoginRequest.java | 0 2 files changed, 4 insertions(+) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CommentUpdateRequest.java rename codeBoy_backend/src/main/java/com/codeboy/mvc/model/{dto => requestDto}/LoginRequest.java (100%) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CommentUpdateRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CommentUpdateRequest.java new file mode 100644 index 0000000..c514c32 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CommentUpdateRequest.java @@ -0,0 +1,4 @@ +package com.codeboy.mvc.model.requestDto; + +public class CommentUpdateRequest { +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/LoginRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/LoginRequest.java similarity index 100% rename from codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/LoginRequest.java rename to codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/LoginRequest.java From 09cdeed58c0b2d83842589909b3c92cf37c744cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=A4=80=ED=98=95?= Date: Thu, 27 Nov 2025 11:06:49 +0900 Subject: [PATCH 16/61] =?UTF-8?q?CommentUpdateRequest=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EA=B3=BC=20Comment=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC?= =?UTF-8?q?=EC=97=90=20=EC=A0=81=EC=9A=A9.=20Memeber,=20Comment=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=C3=AB=EB=9F=AC=EC=9D=98=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EC=9D=84=20PuMaping=20->=20PatchMapping?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mvc/controller/CommentController.java | 13 +++-- .../mvc/controller/MemberController.java | 22 ++++---- .../com/codeboy/mvc/model/dto/Comment.java | 3 +- .../requestDto/CommentUpdateRequest.java | 12 +++++ .../mvc/model/requestDto/LoginRequest.java | 22 ++++---- .../model/requestDto/MemberUpdateRequest.java | 52 ++++++------------- 6 files changed, 62 insertions(+), 62 deletions(-) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java index 6c10b42..9ccef3b 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java @@ -2,6 +2,7 @@ import java.util.List; +import com.codeboy.mvc.model.requestDto.CommentUpdateRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatusCode; import org.springframework.http.ResponseEntity; @@ -32,7 +33,7 @@ public CommentController(CommentService commentService) { @GetMapping("{userProblemSetId}/comments") public ResponseEntity> getAllCommentsById(@PathVariable("userProblemSetId") long userProblemSetId){ List comments = commentService.getAllCommentsById(userProblemSetId); - if(comments.size() > 0) { + if(!comments.isEmpty()) { //성공적으로 댓글들을 조회한 경우 return new ResponseEntity>(comments, HttpStatusCode.valueOf(200)); } @@ -53,9 +54,13 @@ public ResponseEntity addComment(@PathVariable("userProblemSetId") long } - @PutMapping("{userProblemSetId}/comments") - public ResponseEntity updateComment(@PathVariable("commentId") long commentId, @RequestBody Comment comment){ - int result = commentService.updateComment(commentId, comment); + //리소스의 일부(content)만 수정하므로 패치매핑 + @PatchMapping("{userProblemSetId}/comments") + public ResponseEntity updateComment(@PathVariable("commentId") long commentId, @RequestBody CommentUpdateRequest commentUpdateRequest){ + Comment comment = new Comment(); + //Dto를 통해서 받음 + comment.setContent(commentUpdateRequest.getContent()); + int result = commentService.updateComment(commentId, comment); if(result == 1) { //sql의 반환값이 1개면 댓글 업데이트에 성공 return new ResponseEntity("댓글 수정 성공", HttpStatusCode.valueOf(200)); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java index adbe295..d50acc0 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java @@ -1,17 +1,20 @@ package com.codeboy.mvc.controller; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import com.codeboy.mvc.model.requestDto.MemberUpdateRequest; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; import com.codeboy.mvc.model.dto.Member; -import com.codeboy.mvc.model.dto.LoginRequest; -import com.codeboy.mvc.model.dto.MemberUpdateRequest; +import com.codeboy.mvc.model.requestDto.LoginRequest; import com.codeboy.mvc.model.service.MemberService; +import java.net.URI; + @RestController -@RequestMapping("/api/member") +@RequestMapping("/api") @Tag(name="Member RESTful API", description = "Member CRUD를 할 수 있는 REST API") public class MemberController { @@ -31,7 +34,7 @@ public MemberController(MemberService memberService) { * 400 잘못된 요청 * 409 아이디/이메일 중복 */ - @PostMapping("/members") + @PostMapping("/member") public ResponseEntity signUp(@RequestBody Member member) { // TODO: 아이디/이메일 중복 체크 로직은 나중에 추가 int result = memberService.signUp(member); @@ -85,7 +88,8 @@ public ResponseEntity logout() { * 400 잘못된 요청 * 401 인증 실패 */ - @PutMapping("/members/{memberId}") + //회원정보 전체를 업데이트하지않고 일부만 수정하는 거라서 Put에서 Patch매핑으로 변경 + @PatchMapping("/members/{memberId}") public ResponseEntity updateMe(@RequestBody MemberUpdateRequest request, @PathVariable long memberId ) { //파라미터로 memberId받아서 해당회원의 정보를 수정 diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Comment.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Comment.java index 032ad95..bf7599c 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Comment.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Comment.java @@ -13,7 +13,8 @@ @NoArgsConstructor @Getter @Setter -public class Comment { +public class +Comment { private long commentId; private long memberId; private String content; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CommentUpdateRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CommentUpdateRequest.java index c514c32..12f5bdd 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CommentUpdateRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CommentUpdateRequest.java @@ -1,4 +1,16 @@ package com.codeboy.mvc.model.requestDto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Setter public class CommentUpdateRequest { + //댓글을 업데이트할 때 content만 수정하니 수정할 content만 전달하는 DTO + private String content; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/LoginRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/LoginRequest.java index eb40fe4..f8b12cc 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/LoginRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/LoginRequest.java @@ -1,20 +1,16 @@ -package com.codeboy.mvc.model.dto; +package com.codeboy.mvc.model.requestDto; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +@AllArgsConstructor +@NoArgsConstructor +@Setter +@Getter public class LoginRequest { //로그인을 할 때에는 id와 password만 사용하니 이를 간편하게 전달하기 위한 DTO private String id; private String password; - public LoginRequest() {} - - public LoginRequest(String id, String password) { - this.id = id; - this.password = password; - } - - public String getId() { return id; } - public void setId(String id) { this.id = id; } - - public String getPassword() { return password; } - public void setPassword(String password) { this.password = password; } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/MemberUpdateRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/MemberUpdateRequest.java index 8900e9d..b080cd7 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/MemberUpdateRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/MemberUpdateRequest.java @@ -1,37 +1,19 @@ -package com.codeboy.mvc.model.requestDto; + package com.codeboy.mvc.model.requestDto; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; + import io.swagger.v3.oas.annotations.media.Schema; + import lombok.AllArgsConstructor; + import lombok.Getter; + import lombok.NoArgsConstructor; + import lombok.Setter; -@AllArgsConstructor -@NoArgsConstructor -@Getter -@Setter -@Schema(description="유저 정보 수정 DTO") -public class MemberUpdateRequest { - private String nickName; - private String id; - private String email; - public String getNickName() { - return nickName; - } - public void setNickName(String nickName) { - this.nickName = nickName; - } - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public String getEmail() { - return email; - } - public void setEmail(String email) { - this.email = email; - } - -} + @AllArgsConstructor + @NoArgsConstructor + @Getter + @Setter + @Schema(description="유저 정보 수정 DTO") + public class MemberUpdateRequest { + private String nickName; + private String id; + private String email; + + } From f2862fe163bd7573127a13b2e95a4a6a9cacbe58 Mon Sep 17 00:00:00 2001 From: mingeung Date: Thu, 27 Nov 2025 11:07:20 +0900 Subject: [PATCH 17/61] =?UTF-8?q?feat:=20=EC=98=A4=EB=8B=B5=EB=85=B8?= =?UTF-8?q?=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20api=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/codeboy/common/ProblemType.java | 2 +- .../controller/IncorrectNoteController.java | 32 ++++++++++++++++++ .../mvc/model/dao/IncorrectNoteDao.java | 10 ++++-- .../requestDto/IncorrectNoteRequest.java | 16 +++++++++ .../responseDto/IncorrectNoteResponse.java | 19 +++++++++++ .../model/service/IncorrectNoteService.java | 18 ++++++++++ .../service/IncorrectNoteServiceImpl.java | 33 +++++++++++++++++++ .../resources/mappers/IncorrectNoteMapper.xml | 31 +++++++++++++++-- 8 files changed, 154 insertions(+), 7 deletions(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/IncorrectNoteResponse.java diff --git a/codeBoy_backend/src/main/java/com/codeboy/common/ProblemType.java b/codeBoy_backend/src/main/java/com/codeboy/common/ProblemType.java index 80bdc40..c9f9b33 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/common/ProblemType.java +++ b/codeBoy_backend/src/main/java/com/codeboy/common/ProblemType.java @@ -2,5 +2,5 @@ public enum ProblemType { PROBLEM, - USERPROBLEM, + USER_PROBLEM, } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java index 19a3e9d..64c4620 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java @@ -1,4 +1,36 @@ package com.codeboy.mvc.controller; +import com.codeboy.mvc.model.responseDto.ApiResponse; +import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; +import com.codeboy.mvc.model.service.IncorrectNoteServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("api/incorrect-note") public class IncorrectNoteController { + @Autowired + private IncorrectNoteServiceImpl incorrectNoteService; + + //한 회원의 오답노트를 모두 조회 + @GetMapping + public ResponseEntity>> getIncorrectNote(){ + //TODO : 세션에서 memberId 가져오기 + Long memberId = 1L; + if (memberId == null){ + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>( HttpStatus.BAD_REQUEST, "회원 ID를 찾을 수 없습니다.", null)); + } + List incorrectNoteList= incorrectNoteService.getIncorrectNoteList(memberId); + + if (incorrectNoteList == null){ + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "오답노트를 조회하는 데 실패하였습니다.", null)); + } + return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(HttpStatus.OK, "오답노트가 성공적으로 조회되었습니다", incorrectNoteList)); + } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java index 938eab0..06a309a 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java @@ -1,20 +1,24 @@ package com.codeboy.mvc.model.dao; import java.util.List; +import java.util.Map; import com.codeboy.common.ProblemType; import com.codeboy.mvc.model.dto.Problem; +import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; public interface IncorrectNoteDao { //유저의 아이디로 유저가 틀린 문제들의 모음을 조회 - public List selectIncorrectProblems(long memberId); + //sql의 관점에서 + // + public List selectIncorrectProblems(long memberId); //유저가 자신의 오답노트 안에서 문제를 삭제 - public void deleteIncorrectProblem(long memberId, long incorrectNoteId); + public void deleteIncorrectProblem( long incorrectNoteId); //오답노트에 문제 추가 - public void insertIncorrectProblem(long memberId, long problemId, long userProblemId, ProblemType problemType); + public void insertIncorrectProblem(Map params); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java new file mode 100644 index 0000000..623ea9e --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java @@ -0,0 +1,16 @@ +package com.codeboy.mvc.model.requestDto; + +import com.codeboy.common.ProblemType; +import lombok.*; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class IncorrectNoteRequest { + private Long memberId; + private Long problemId; + private Long userProblemId; + private ProblemType problemType; +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/IncorrectNoteResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/IncorrectNoteResponse.java new file mode 100644 index 0000000..977d973 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/IncorrectNoteResponse.java @@ -0,0 +1,19 @@ +package com.codeboy.mvc.model.responseDto; + +import lombok.*; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Setter +public class IncorrectNoteResponse { + private Long incorrectNoteId; + private String problemDescription; + private String choice1; + private String choice2; + private String choice3; + private String choice4; + private String answer; + private String category; +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java index c784d5a..7ce0b40 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java @@ -1,5 +1,23 @@ package com.codeboy.mvc.model.service; +import com.codeboy.common.ProblemType; +import com.codeboy.mvc.model.dto.IncorrectNote; +import com.codeboy.mvc.model.dto.Problem; +import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service public interface IncorrectNoteService { + //오답노트에 문제 넣기 + public void addIncorrectNote(Long memberId, Long problemId, Long userProblemId, ProblemType problemType); + //한 유저의 모든 오답노트 조회하기 + public List getIncorrectNoteList(long memberId); + + //오답노트 삭제하기 + public void deleteIncorrectNote(long incorrectNoteId); + + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java index 0d6f710..2f1e455 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java @@ -1,4 +1,37 @@ package com.codeboy.mvc.model.service; +import com.codeboy.common.ProblemType; +import com.codeboy.mvc.model.dao.IncorrectNoteDao; +import com.codeboy.mvc.model.dto.Problem; +import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class IncorrectNoteServiceImpl implements IncorrectNoteService{ + @Autowired + private IncorrectNoteDao incorrectNoteDao; + + @Override + public void addIncorrectNote(Long memberId, Long problemId, Long userProblemId, ProblemType problemType) { + Map params = new HashMap<>(); + params.put("memberId", memberId); + params.put("problemId", problemId); + params.put("userProblemId", userProblemId); + params.put("problemType", problemType); + + incorrectNoteDao.insertIncorrectProblem(params); + } + + @Override + public List getIncorrectNoteList(long memberId) { + return incorrectNoteDao.selectIncorrectProblems(memberId); + } + + @Override + public void deleteIncorrectNote(long incorrectNoteId) { + incorrectNoteDao.deleteIncorrectProblem(incorrectNoteId); + } } diff --git a/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml b/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml index e69cd46..0554bd0 100644 --- a/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml @@ -5,9 +5,34 @@ From 719e3d2d8f7ae541ee4ab2aa2a4c0c3d7ba16ded Mon Sep 17 00:00:00 2001 From: mingeung Date: Thu, 27 Nov 2025 13:31:42 +0900 Subject: [PATCH 18/61] =?UTF-8?q?feat:=20=EC=98=A4=EB=8B=B5=EB=85=B8?= =?UTF-8?q?=ED=8A=B8=20=EC=A1=B0=ED=9A=8C,=20=EC=82=AD=EC=A0=9C,=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/IncorrectNoteController.java | 52 +++++++++++++++++-- .../mvc/model/dao/IncorrectNoteDao.java | 6 ++- .../requestDto/IncorrectNoteRequest.java | 1 - .../responseDto/IncorrectNoteResponse.java | 3 +- .../model/service/IncorrectNoteService.java | 23 -------- .../service/IncorrectNoteServiceImpl.java | 16 +++--- .../resources/mappers/IncorrectNoteMapper.xml | 18 +++---- 7 files changed, 72 insertions(+), 47 deletions(-) delete mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java index 64c4620..8c3f26b 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java @@ -1,14 +1,14 @@ package com.codeboy.mvc.controller; +import com.codeboy.common.ProblemType; +import com.codeboy.mvc.model.requestDto.IncorrectNoteRequest; import com.codeboy.mvc.model.responseDto.ApiResponse; import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; import com.codeboy.mvc.model.service.IncorrectNoteServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; @@ -33,4 +33,50 @@ public ResponseEntity>> getIncorrectNote } return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(HttpStatus.OK, "오답노트가 성공적으로 조회되었습니다", incorrectNoteList)); } + + //오답노트에 문제 넣기 + @PostMapping + public ResponseEntity> addIncorrectNote(@RequestBody IncorrectNoteRequest incorrectNoteRequest){ + //TODO : 세션에서 멤버 id 가져오기 + Long memberId = 1L; + Long problemId = incorrectNoteRequest.getProblemId(); + Long userProblemId = incorrectNoteRequest.getUserProblemId(); + ProblemType problemType = incorrectNoteRequest.getProblemType(); + + if (memberId == null){ + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "멤버 ID가 유효하지 않습니다.", null)); + } + if (problemType == ProblemType.PROBLEM) { + if (!( problemId != null && userProblemId == null)) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "문제 ID가 유효하지 않습니다.", null)); + } + + } + if (problemType == ProblemType.USER_PROBLEM) { + if (!( problemId == null && userProblemId != null)) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "유저 문제 ID가 유효하지 않습니다.", null)); + } + } +// else if (problemType == null){ +// return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "ProblemType이 유효하지 않습니다.", null)); +// } + Long incorrectNoteId = incorrectNoteService.addIncorrectNote(memberId,problemId,userProblemId,problemType); + + if (incorrectNoteId == null){ + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "오답노트 생성에 실패하였습니다.", null)); + } + return ResponseEntity.status(HttpStatus.CREATED).body(new ApiResponse<>(HttpStatus.CREATED, "오답노트를 성공적으로 생성하였습니다.",incorrectNoteId )); + } + + @DeleteMapping("/{incorrectNoteId}") + public ResponseEntity> deleteIncorrectNote(@PathVariable long incorrectNoteId){ + + boolean isDeleted = incorrectNoteService.deleteIncorrectNote(incorrectNoteId); + if (!isDeleted){ + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "유효하지 않은 오답노트입니다.", null)); + } + return ResponseEntity.ok(new ApiResponse<>(HttpStatus.OK, "오답노트가 삭제되었습니다", null)); + } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java index 06a309a..198d4e4 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java @@ -6,7 +6,9 @@ import com.codeboy.common.ProblemType; import com.codeboy.mvc.model.dto.Problem; import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; +import org.apache.ibatis.annotations.Mapper; +@Mapper public interface IncorrectNoteDao { //유저의 아이디로 유저가 틀린 문제들의 모음을 조회 @@ -15,10 +17,10 @@ public interface IncorrectNoteDao { public List selectIncorrectProblems(long memberId); //유저가 자신의 오답노트 안에서 문제를 삭제 - public void deleteIncorrectProblem( long incorrectNoteId); + public int deleteIncorrectProblem( long incorrectNoteId); //오답노트에 문제 추가 - public void insertIncorrectProblem(Map params); + public Long insertIncorrectProblem(Map params); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java index 623ea9e..62d4324 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java @@ -9,7 +9,6 @@ @Setter @ToString public class IncorrectNoteRequest { - private Long memberId; private Long problemId; private Long userProblemId; private ProblemType problemType; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/IncorrectNoteResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/IncorrectNoteResponse.java index 977d973..58cafcd 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/IncorrectNoteResponse.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/IncorrectNoteResponse.java @@ -1,5 +1,6 @@ package com.codeboy.mvc.model.responseDto; +import com.codeboy.common.Category; import lombok.*; @Data @@ -15,5 +16,5 @@ public class IncorrectNoteResponse { private String choice3; private String choice4; private String answer; - private String category; + private Category category; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java deleted file mode 100644 index 7ce0b40..0000000 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.codeboy.mvc.model.service; - -import com.codeboy.common.ProblemType; -import com.codeboy.mvc.model.dto.IncorrectNote; -import com.codeboy.mvc.model.dto.Problem; -import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -public interface IncorrectNoteService { - //오답노트에 문제 넣기 - public void addIncorrectNote(Long memberId, Long problemId, Long userProblemId, ProblemType problemType); - //한 유저의 모든 오답노트 조회하기 - public List getIncorrectNoteList(long memberId); - - //오답노트 삭제하기 - public void deleteIncorrectNote(long incorrectNoteId); - - - -} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java index 2f1e455..74d629c 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java @@ -5,33 +5,33 @@ import com.codeboy.mvc.model.dto.Problem; import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.List; import java.util.Map; -public class IncorrectNoteServiceImpl implements IncorrectNoteService{ +@Service +public class IncorrectNoteServiceImpl{ @Autowired private IncorrectNoteDao incorrectNoteDao; - @Override - public void addIncorrectNote(Long memberId, Long problemId, Long userProblemId, ProblemType problemType) { + public Long addIncorrectNote(Long memberId, Long problemId, Long userProblemId, ProblemType problemType) { Map params = new HashMap<>(); params.put("memberId", memberId); params.put("problemId", problemId); params.put("userProblemId", userProblemId); params.put("problemType", problemType); - incorrectNoteDao.insertIncorrectProblem(params); + return incorrectNoteDao.insertIncorrectProblem(params); } - @Override public List getIncorrectNoteList(long memberId) { return incorrectNoteDao.selectIncorrectProblems(memberId); } - @Override - public void deleteIncorrectNote(long incorrectNoteId) { - incorrectNoteDao.deleteIncorrectProblem(incorrectNoteId); + public boolean deleteIncorrectNote(long incorrectNoteId) { + int deleted = incorrectNoteDao.deleteIncorrectProblem(incorrectNoteId); + return deleted > 0; } } diff --git a/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml b/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml index 0554bd0..498075e 100644 --- a/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml @@ -21,13 +21,13 @@ ) UNION ALL (SELECT inote.incorrect_note_id, - p.problem_description, - p.choice_1 AS choice1, - p.choice_2 AS choice2, - p.choice_3 AS choice3, - p.choice_4 AS choice4, - p.answer, - p.category + u.problem_description, + u.choice_1 AS choice1, + u.choice_2 AS choice2, + u.choice_3 AS choice3, + u.choice_4 AS choice4, + u.answer, + u.category FROM incorrect_note inote JOIN user_problem u ON inote.problem_id = u.user_problem_id WHERE inote.member_id = #{memberId} @@ -35,13 +35,13 @@ ) - + DELETE FROM incorrect_note WHERE incorrect_note_id = #{incorrectNoteId} - + INSERT INTO incorrect_note (member_id, problem_id, user_problem_id, problem_type) VALUES (#{memberId}, #{problemId}, #{userProblemId}, #{problemType}) From c79d116c621879bbfc34c9cb48950e3ec74c770f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=A4=80=ED=98=95?= Date: Thu, 27 Nov 2025 15:15:15 +0900 Subject: [PATCH 19/61] =?UTF-8?q?feat:=20Comment=20=EC=88=98=EC=A0=95=201.?= =?UTF-8?q?=20CommentServiceImpl=EC=97=90=20userProlemSetId=EC=9D=98=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20->long=202.=20Comment=20Controller=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codeBoy_backend/.gitignore | 2 + .../mvc/controller/CommentController.java | 164 +++++++++++++----- .../com/codeboy/mvc/model/dao/CommentDao.java | 4 + .../mvc/model/dao/UserProblemSetDao.java | 12 ++ .../requestDto/CommentUpdateRequest.java | 1 + .../mvc/model/responseDto/ApiResponse.java | 17 +- .../mvc/model/service/CommentService.java | 5 +- .../mvc/model/service/CommentServiceImpl.java | 6 +- .../main/resources/mappers/CommentMapper.xml | 3 + .../src/main/resources/mappers/UserMapper.xml | 0 .../mappers/UserProblemSetMapper.xml | 11 ++ 11 files changed, 174 insertions(+), 51 deletions(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java delete mode 100644 codeBoy_backend/src/main/resources/mappers/UserMapper.xml create mode 100644 codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml diff --git a/codeBoy_backend/.gitignore b/codeBoy_backend/.gitignore index c5d3e1f..4f0d27e 100644 --- a/codeBoy_backend/.gitignore +++ b/codeBoy_backend/.gitignore @@ -32,3 +32,5 @@ build/ ### VS Code ### .vscode/ /.metadata/ + +.class \ No newline at end of file diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java index 9ccef3b..1d7198d 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java @@ -1,17 +1,19 @@ package com.codeboy.mvc.controller; +import java.util.ArrayList; import java.util.List; import com.codeboy.mvc.model.requestDto.CommentUpdateRequest; +import com.codeboy.mvc.model.responseDto.ApiResponse; +import jakarta.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatusCode; +import org.springframework.http.HttpStatus; 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.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -30,56 +32,126 @@ public CommentController(CommentService commentService) { } - @GetMapping("{userProblemSetId}/comments") - public ResponseEntity> getAllCommentsById(@PathVariable("userProblemSetId") long userProblemSetId){ + @GetMapping("{userProblemSetId}") + //숫자가 아닌 값이 userProblemSetId에 오면 스프링이 컨트롤러에 도달하기전에 400BAD_REQUEST를 보내줌 + public ResponseEntity>> getAllCommentsById(@PathVariable("userProblemSetId") long userProblemSetId){ List comments = commentService.getAllCommentsById(userProblemSetId); - if(!comments.isEmpty()) { - //성공적으로 댓글들을 조회한 경우 - return new ResponseEntity>(comments, HttpStatusCode.valueOf(200)); - } - //댓글 조회에 실패한 경우 - return new ResponseEntity>(HttpStatusCode.valueOf(404)); - } - - @PostMapping("{userProblemSetId}/comments") - public ResponseEntity addComment(@PathVariable("userProblemSetId") long userProblemSetId, @RequestBody Comment comment){ - int result = commentService.addComment(userProblemSetId, comment); - if(result == 1) { - //sql의 반환값이 1개면 댓글 추가에 성공한 경우 - return new ResponseEntity("댓글 추가 성공", HttpStatusCode.valueOf(200)); - } - //서버 오류로 댓글 추가에 실패한 경우 - return new ResponseEntity("댓글 추가 실패", HttpStatusCode.valueOf(500)); + if (comments.isEmpty()) { + //댓글이 달리지 않은 경우 + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "댓글이 없습니다.", new ArrayList())); + } + //댓글 조회에 성공한 경우 + return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "댓글 조회 성공", comments)); } - + + @PostMapping("{userProblemSetId}") + public ResponseEntity> addComment(@PathVariable long userProblemSetId, + @RequestBody Comment comment) { + if (comment.getContent() == null || comment.getContent().isBlank()) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "댓글 내용은 비어 있을 수 없습니다.")); + } + + int result = commentService.addComment(userProblemSetId, comment); + + if (result == 0) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "댓글 추가 실패")); + } + + return ResponseEntity.status(HttpStatus.CREATED) + .body(ApiResponse.success(HttpStatus.CREATED, "댓글 추가 성공", null)); + } + + //리소스의 일부(content)만 수정하므로 패치매핑 - @PatchMapping("{userProblemSetId}/comments") - public ResponseEntity updateComment(@PathVariable("commentId") long commentId, @RequestBody CommentUpdateRequest commentUpdateRequest){ + @PatchMapping("{userProblemSetId}/{commentId}") + public ResponseEntity> updateComment( + @PathVariable long userProblemSetId, + @PathVariable long commentId, + @RequestBody CommentUpdateRequest commentUpdateRequest, + HttpSession session) { + + Long memberId = (Long) session.getAttribute("member_id"); + if (memberId == null) { + // 인증 안 됨 + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); + } + + if (!memberId.equals(commentUpdateRequest.getMemberId())) { + // 인가 실패 + // 로그인 중인 회원이 자신이 작성한 댓글이 아닌 것을 수정하려할 때 + return ResponseEntity.status(HttpStatus.FORBIDDEN) + .body(ApiResponse.failure(HttpStatus.FORBIDDEN, "본인의 댓글만 수정할 수 있습니다.")); + } + + //댓글이 비어있을 때 + if (commentUpdateRequest.getContent() == null || commentUpdateRequest.getContent().isBlank()) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "수정할 댓글 내용을 입력해주세요.")); + } + Comment comment = new Comment(); - //Dto를 통해서 받음 comment.setContent(commentUpdateRequest.getContent()); + int result = commentService.updateComment(commentId, comment); - if(result == 1) { - //sql의 반환값이 1개면 댓글 업데이트에 성공 - return new ResponseEntity("댓글 수정 성공", HttpStatusCode.valueOf(200)); - } - //댓글 아이디가 존재하지 않을 경우, 업데이트 실패 - return new ResponseEntity("존재 하지 않는 댓글입니다.", HttpStatusCode.valueOf(404)); - - } - - @DeleteMapping("{userProblemSetId}/comments") - public ResponseEntity deleteComment(@PathVariable("commentId") long commentId){ - int result = commentService.deleteComment(commentId); - if(result == 1) { - //sql의 반환값이 1개면 댓글 삭제에 성공 - return new ResponseEntity("댓글 삭제 성공", HttpStatusCode.valueOf(200)); - } - //댓글 아이디가 존재하지 않을 경우, 삭제에 실패 - return new ResponseEntity("존재 하지 않는 댓글입니다.", HttpStatusCode.valueOf(404)); - - } - + + if (result == 0) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(ApiResponse.failure(HttpStatus.NOT_FOUND, "존재하지 않는 댓글입니다.")); + + } + + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "댓글 수정 성공", null)); + } + + + @DeleteMapping("{userProblemSetId}/{commentId}") + public ResponseEntity> deleteComment(@PathVariable long userProblemSetId, + @PathVariable long commentId, + HttpSession session) { + + Long memberId = (Long) session.getAttribute("member_id"); + + // 로그인 안한 상태 + if (memberId == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); + } + + // DB에서 댓글 작성자 ID 조회 + Long ownerId = commentService.getCommentOwnerId(commentId); + + // 댓글ID가 존재하지 않는 경우 + if (ownerId == null) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(ApiResponse.failure(HttpStatus.NOT_FOUND, "존재하지 않는 댓글입니다.")); + } + + // 권한 없음 (본인 댓글 아님) + if (!memberId.equals(ownerId)) { + return ResponseEntity.status(HttpStatus.FORBIDDEN) + .body(ApiResponse.failure(HttpStatus.FORBIDDEN, "본인이 작성한 댓글만 삭제할 수 있습니다.")); + } + + // 삭제 실행 + int result = commentService.deleteComment(commentId); + + if (result == 0) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "댓글 삭제에 실패했습니다.")); + } + + // 삭제 실패 (DB 오류 등의 상황) + + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "댓글 삭제 성공", null)); + } + + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java index 1852c42..bdd2b8c 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java @@ -18,4 +18,8 @@ public interface CommentDao { //조회된 댓글의 id를 가져와서 수정하고 삭제함. public int deleteComment(long commentId); + + //댓글아이디로 댓글 작성자의 아이디를 가져옴 + public Long selectCommentOwnerId(long commentId); + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java new file mode 100644 index 0000000..14bc58d --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java @@ -0,0 +1,12 @@ +package com.codeboy.mvc.model.dao; + +import com.codeboy.mvc.model.dto.Problem; + +import java.util.List; + +public interface UserProblemSetDao { + public List selectProblemsByUserProblemSetId(long userProblemSetId); + + + +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CommentUpdateRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CommentUpdateRequest.java index 12f5bdd..86d9c21 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CommentUpdateRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CommentUpdateRequest.java @@ -13,4 +13,5 @@ public class CommentUpdateRequest { //댓글을 업데이트할 때 content만 수정하니 수정할 content만 전달하는 DTO private String content; + private long memberId; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java index eac7fd1..d191ec4 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java @@ -3,15 +3,28 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.springframework.http.HttpStatus; @Data @AllArgsConstructor @NoArgsConstructor public class ApiResponse { - private boolean success; + private HttpStatus status; private String message; private T data; + public static ApiResponse success(HttpStatus status, T data) { + return new ApiResponse<>(status, null, data); + } + + public static ApiResponse success(HttpStatus status, String message, T data) { + return new ApiResponse<>(status, message, data); + } + + public static ApiResponse failure(HttpStatus status, String message) { + return new ApiResponse<>(status, message, null); + } - // getter, setter 생략 } + + diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java index 779b154..c96e672 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java @@ -14,6 +14,7 @@ public interface CommentService { public int updateComment(long commentId, Comment comment); // public int deleteComment(long commentId); - - + + public Long getCommentOwnerId(long commentId); + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java index 49bbefe..44ae5be 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java @@ -28,6 +28,7 @@ public List getAllCommentsById(long userProblemSetId) { @Override public int addComment(long userProblemSetId, Comment comment ) { + return commentDao.insertComment(userProblemSetId, comment); } @@ -48,7 +49,10 @@ public int deleteComment(long commentId) { } - + @Override + public Long getCommentOwnerId(long commentId){ + return commentDao.selectCommentOwnerId(commentId); + } } diff --git a/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml b/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml index 29e730f..eca08ca 100644 --- a/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml @@ -27,4 +27,7 @@ WHERE comment_id = #{commentId} + diff --git a/codeBoy_backend/src/main/resources/mappers/UserMapper.xml b/codeBoy_backend/src/main/resources/mappers/UserMapper.xml deleted file mode 100644 index e69de29..0000000 diff --git a/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml b/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml new file mode 100644 index 0000000..c42da7e --- /dev/null +++ b/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml @@ -0,0 +1,11 @@ + + + + + + + + From 12e838c5bdfcede1e8a0d9f43e9825572f2a41cc Mon Sep 17 00:00:00 2001 From: mingeung Date: Thu, 27 Nov 2025 15:17:37 +0900 Subject: [PATCH 20/61] =?UTF-8?q?feat:=20=EC=98=A4=EB=8B=B5=EB=85=B8?= =?UTF-8?q?=ED=8A=B8=20API=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20Servic?= =?UTF-8?q?e=EC=97=90=EC=84=9C=20=EC=B2=B4=ED=81=AC=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/codeboy/common/ProblemType.java | 6 -- .../controller/IncorrectNoteController.java | 78 +++++++---------- .../mvc/controller/QuizRoomController.java | 64 +++++++------- .../mvc/model/dao/IncorrectNoteDao.java | 16 ++-- .../codeboy/mvc/model/dto/IncorrectNote.java | 3 +- .../requestDto/IncorrectNoteRequest.java | 3 +- .../mvc/model/responseDto/ApiResponse.java | 11 ++- .../model/service/IncorrectNoteService.java | 86 +++++++++++++++++++ .../service/IncorrectNoteServiceImpl.java | 37 -------- .../mvc/model/service/QuizRoomService.java | 51 ++++++++--- .../model/service/QuizRoomServiceImpl.java | 59 ------------- .../resources/mappers/IncorrectNoteMapper.xml | 32 +++++-- 12 files changed, 233 insertions(+), 213 deletions(-) delete mode 100644 codeBoy_backend/src/main/java/com/codeboy/common/ProblemType.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java delete mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java delete mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java diff --git a/codeBoy_backend/src/main/java/com/codeboy/common/ProblemType.java b/codeBoy_backend/src/main/java/com/codeboy/common/ProblemType.java deleted file mode 100644 index c9f9b33..0000000 --- a/codeBoy_backend/src/main/java/com/codeboy/common/ProblemType.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.codeboy.common; - -public enum ProblemType { - PROBLEM, - USER_PROBLEM, -} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java index 8c3f26b..fd778bf 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java @@ -1,11 +1,10 @@ package com.codeboy.mvc.controller; -import com.codeboy.common.ProblemType; import com.codeboy.mvc.model.requestDto.IncorrectNoteRequest; import com.codeboy.mvc.model.responseDto.ApiResponse; import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; -import com.codeboy.mvc.model.service.IncorrectNoteServiceImpl; -import org.springframework.beans.factory.annotation.Autowired; +import com.codeboy.mvc.model.service.IncorrectNoteService; +import org.apache.ibatis.javassist.NotFoundException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -15,68 +14,55 @@ @RestController @RequestMapping("api/incorrect-note") public class IncorrectNoteController { - @Autowired - private IncorrectNoteServiceImpl incorrectNoteService; + + private final IncorrectNoteService incorrectNoteService; + + public IncorrectNoteController(IncorrectNoteService incorrectNoteService) { + this.incorrectNoteService = incorrectNoteService; + } //한 회원의 오답노트를 모두 조회 @GetMapping - public ResponseEntity>> getIncorrectNote(){ - //TODO : 세션에서 memberId 가져오기 - Long memberId = 1L; - if (memberId == null){ - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>( HttpStatus.BAD_REQUEST, "회원 ID를 찾을 수 없습니다.", null)); - } - List incorrectNoteList= incorrectNoteService.getIncorrectNoteList(memberId); - - if (incorrectNoteList == null){ - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "오답노트를 조회하는 데 실패하였습니다.", null)); + public ResponseEntity>> getIncorrectNote() { + try { + //TODO : 세션 or spring security에서 memberId 가져오기 + Long memberId = 1L; + List incorrectNoteList = incorrectNoteService.getIncorrectNoteList(memberId); + return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "오답노트가 성공적으로 조회되었습니다", incorrectNoteList)); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } catch (NotFoundException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.failure(HttpStatus.NOT_FOUND, e.getMessage())); } - return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(HttpStatus.OK, "오답노트가 성공적으로 조회되었습니다", incorrectNoteList)); } //오답노트에 문제 넣기 @PostMapping - public ResponseEntity> addIncorrectNote(@RequestBody IncorrectNoteRequest incorrectNoteRequest){ + public ResponseEntity> addIncorrectNote(@RequestBody IncorrectNoteRequest incorrectNoteRequest) { //TODO : 세션에서 멤버 id 가져오기 Long memberId = 1L; Long problemId = incorrectNoteRequest.getProblemId(); Long userProblemId = incorrectNoteRequest.getUserProblemId(); - ProblemType problemType = incorrectNoteRequest.getProblemType(); + Boolean isUserProblem = incorrectNoteRequest.getIsUserProblem(); - if (memberId == null){ - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "멤버 ID가 유효하지 않습니다.", null)); - } - if (problemType == ProblemType.PROBLEM) { - if (!( problemId != null && userProblemId == null)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "문제 ID가 유효하지 않습니다.", null)); - } + try { + Long incorrectNoteId = incorrectNoteService.addIncorrectNote(memberId, problemId, userProblemId, isUserProblem); + return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(HttpStatus.CREATED, "오답노트를 성공적으로 생성하였습니다.", incorrectNoteId)); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); } - if (problemType == ProblemType.USER_PROBLEM) { - if (!( problemId == null && userProblemId != null)) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "유저 문제 ID가 유효하지 않습니다.", null)); - } - } -// else if (problemType == null){ -// return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "ProblemType이 유효하지 않습니다.", null)); -// } - Long incorrectNoteId = incorrectNoteService.addIncorrectNote(memberId,problemId,userProblemId,problemType); - if (incorrectNoteId == null){ - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "오답노트 생성에 실패하였습니다.", null)); - } - return ResponseEntity.status(HttpStatus.CREATED).body(new ApiResponse<>(HttpStatus.CREATED, "오답노트를 성공적으로 생성하였습니다.",incorrectNoteId )); } @DeleteMapping("/{incorrectNoteId}") - public ResponseEntity> deleteIncorrectNote(@PathVariable long incorrectNoteId){ + public ResponseEntity> deleteIncorrectNote(@PathVariable long incorrectNoteId) { - boolean isDeleted = incorrectNoteService.deleteIncorrectNote(incorrectNoteId); - if (!isDeleted){ - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "유효하지 않은 오답노트입니다.", null)); - } - return ResponseEntity.ok(new ApiResponse<>(HttpStatus.OK, "오답노트가 삭제되었습니다", null)); + try { + incorrectNoteService.deleteIncorrectNote(incorrectNoteId); + return ResponseEntity.ok(ApiResponse.success(HttpStatus.OK, "오답노트가 삭제되었습니다")); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java index 659c2e2..4be9763 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java @@ -3,33 +3,32 @@ import com.codeboy.mvc.model.requestDto.CreateQuizRoomRequest; import com.codeboy.mvc.model.requestDto.JoinQuizRoomRequest; import com.codeboy.mvc.model.responseDto.ApiResponse; +import com.codeboy.mvc.model.service.IncorrectNoteService; +import com.codeboy.mvc.model.service.QuizRoomService; import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import com.codeboy.mvc.model.service.QuizRoomServiceImpl; import javax.sql.DataSource; -import java.sql.SQLException; import java.util.List; @RestController @RequestMapping("/api/quiz-room") public class QuizRoomController { - @Autowired - private DataSource dataSource; - - @Autowired - private QuizRoomServiceImpl quizRoomService; - - @PostConstruct - public void testConnection() throws SQLException { - System.out.println("연결확인" + dataSource.getConnection()); + + + private final QuizRoomService quizRoomService; + + public QuizRoomController(QuizRoomService quizRoomService){ + this.quizRoomService = quizRoomService; } - //호스트 - 퀴즈방 만들기 + + + //호스트 - 퀴즈방 만들기 @PostMapping("/create") //TODO : 로그인 구현되면 memberId를 requestBody로 넘기지 말고 세션에서 가져오도록 하기 public ResponseEntity> createQuizRoom(@RequestBody CreateQuizRoomRequest request) { @@ -38,14 +37,13 @@ public ResponseEntity> createQuizRoom(@RequestBody CreateQuizR //1. memberId가 유효한지 체크 //TODO : membertable에서 해당 멤버가 있는지 확인하는 조건 추가 if (memberId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "멤버ID가 유효하지 않습니다.", null - )); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "멤버ID가 유효하지 않습니다.")); } //2. 새로운 채팅방 생성하기 long quizRoomId = quizRoomService.createQuizRoom(); if (quizRoomId <= 0) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "새로운 퀴즈방 생성에 실패했습니다. ", null)); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.failure(HttpStatus.NOT_FOUND, "새로운 퀴즈방 생성에 실패했습니다")); } //3. QuizRoomMember 객체 생성 QuizRoomMember quizRoomMember = new QuizRoomMember(); @@ -58,9 +56,9 @@ public ResponseEntity> createQuizRoom(@RequestBody CreateQuizR boolean isOk = quizRoomService.joinQuizRoom(quizRoomMember); if (!isOk) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "호스트를 퀴즈방에 넣는 과정이 실패했습니다. ", null)); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.failure(HttpStatus.NOT_FOUND, "호스트를 퀴즈방에 넣는 과정이 실패했습니다.")); } - return ResponseEntity.status(HttpStatus.CREATED).body(new ApiResponse<>(HttpStatus.CREATED, "퀴즈방이 성공적으로 생성되었습니다.", quizRoomId)); + return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(HttpStatus.CREATED, "퀴즈방이 성공적으로 생성되었습니다.", quizRoomId)); } //채팅방 참여하기 @@ -71,18 +69,19 @@ public ResponseEntity> joinQuizRoom(@RequestBody JoinQuizRoo long roomId = request.getRoomId(); //TODO : 멤버 ID가 DB에 있는지 확인하는 과정 if (memberId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "멤버ID가 유효하지 않습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "멤버ID가 유효하지 않습니다.")); } //TODO : 채팅방 인원이 초과되었는지 확인하는 메서드 추가 //퀴즈방 기본 검증 if (roomId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "퀴즈방ID가 유효하지 않습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "퀴즈방ID가 유효하지 않습니다.")); } //퀴즈방이 존재하는지 확인 boolean roomExists = quizRoomService.existsQuizRoom(roomId); if (!roomExists) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "존재하지 않는 퀴즈방입니다.", null) - ); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.failure(HttpStatus.NOT_FOUND, "존재하지 않는 퀴즈방입니다.")); + + } //QuizRoomMember 생성 QuizRoomMember quizRoomMember = new QuizRoomMember(); @@ -94,9 +93,9 @@ public ResponseEntity> joinQuizRoom(@RequestBody JoinQuizRoo boolean isOk = quizRoomService.joinQuizRoom(quizRoomMember); if (!isOk) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "퀴즈방 입장에 실패하였습니다. ", null)); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.failure(HttpStatus.NOT_FOUND, "퀴즈방 입장에 실패하였습니다.")); } - return ResponseEntity.status(HttpStatus.CREATED).body(new ApiResponse<>(HttpStatus.CREATED, "퀴즈방 입장에 성공하였습니다.", null)); + return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(HttpStatus.CREATED, "퀴즈방 입장에 성공하였습니다.")); } //채팅방 목록 보여주기 @@ -104,12 +103,12 @@ public ResponseEntity> joinQuizRoom(@RequestBody JoinQuizRoo public ResponseEntity>> getQuizRoomList() { List quizRooms = quizRoomService.getQuizRoomList(); if (quizRooms == null) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "퀴즈방 정보를 가져오지 못했습니다", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "퀴즈방 정보를 가져오지 못했습니다")); } else if (quizRooms.isEmpty()) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST,"생성된 퀴즈방이 없습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "생성된 퀴즈방이 없습니다.")); } - return ResponseEntity.status(HttpStatus.OK) .body(new ApiResponse<>(HttpStatus.OK, "퀴즈방 목록 조회 성공", quizRooms)); + return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "퀴즈방 목록 조회 성공", quizRooms)); } @@ -118,16 +117,16 @@ else if (quizRooms.isEmpty()) { @GetMapping("/{roomId}/member") public ResponseEntity>> getQuizRoomMembers(@PathVariable long roomId) { if (roomId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "퀴즈방 ID가 유효하지 않습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "퀴즈방 ID가 유효하지 않습니다.")); } List memberList = quizRoomService.getOneQuizRoomMember(roomId); //TODO : member API 와 연결해서 참가 중인 멤버 닉네임을 보여주도록? if (!memberList.isEmpty()) { - return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(HttpStatus.OK, "멤버 리스트를 반환합니다.", memberList )); + return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "멤버 리스트를 반환합니다.", memberList)); } - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiResponse<>(HttpStatus.NOT_FOUND, "참가자가 없습니다.", null)); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.failure(HttpStatus.NOT_FOUND, "참가자가 없습니다.")); } @@ -135,14 +134,13 @@ public ResponseEntity>> getQuizRoomMembers(@Pat @DeleteMapping("/{roomId}") public ResponseEntity> deleteQuizRoom(@PathVariable long roomId) { if (roomId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "퀴즈방 ID가 유효하지 않습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "퀴즈방 ID가 유효하지 않습니다.")); } boolean isOk = quizRoomService.deleteQuizRoom(roomId); if (!isOk) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "퀴즈방 삭제에 실패했습니다.", null)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "퀴즈방 삭제에 실패했습니다.")); } - return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(HttpStatus.OK, "성공적으로 퀴즈방이 삭제되었습니다. ", null - )); + return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "성공적으로 퀴즈방이 삭제되었습니다.")); } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java index 198d4e4..0baf64e 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java @@ -3,8 +3,6 @@ import java.util.List; import java.util.Map; -import com.codeboy.common.ProblemType; -import com.codeboy.mvc.model.dto.Problem; import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; import org.apache.ibatis.annotations.Mapper; @@ -14,13 +12,21 @@ public interface IncorrectNoteDao { //유저의 아이디로 유저가 틀린 문제들의 모음을 조회 //sql의 관점에서 // - public List selectIncorrectProblems(long memberId); + public List selectIncorrectProblems(Long memberId); //유저가 자신의 오답노트 안에서 문제를 삭제 - public int deleteIncorrectProblem( long incorrectNoteId); + public int deleteIncorrectProblem(Long incorrectNoteId); //오답노트에 문제 추가 public Long insertIncorrectProblem(Map params); -} + //문제 존재 여부 체크 + boolean existsProblemById(Long problemId); + + //유저 문제 존재 여부 체크 + boolean existsUserProblemById(Long userProblemId); + //incorrectNoteId 존재 여부 체크 + boolean existsIncorrectNoteById(Long incorrectNoteId); + +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/IncorrectNote.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/IncorrectNote.java index 477c233..25f213d 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/IncorrectNote.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/IncorrectNote.java @@ -1,6 +1,5 @@ package com.codeboy.mvc.model.dto; -import com.codeboy.common.ProblemType; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Getter; @@ -17,5 +16,5 @@ public class IncorrectNote { private long memberId; private long problemId; private long userProblemId; - private ProblemType ProblemType; + private Boolean isUserProblem; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java index 62d4324..2ab3592 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java @@ -1,6 +1,5 @@ package com.codeboy.mvc.model.requestDto; -import com.codeboy.common.ProblemType; import lombok.*; @NoArgsConstructor @@ -11,5 +10,5 @@ public class IncorrectNoteRequest { private Long problemId; private Long userProblemId; - private ProblemType problemType; + private Boolean isUserProblem; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java index 83718ae..5960232 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java @@ -13,6 +13,15 @@ public class ApiResponse { private String message; private T data; + public static ApiResponse success(HttpStatus status, T data) { + return new ApiResponse<>(status, null, data); + } - // getter, setter 생략 + public static ApiResponse success(HttpStatus status, String message, T data) { + return new ApiResponse<>(status, message, data); + } + + public static ApiResponse failure(HttpStatus status, String message) { + return new ApiResponse<>(status, message, null); + } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java new file mode 100644 index 0000000..50ec94b --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java @@ -0,0 +1,86 @@ +package com.codeboy.mvc.model.service; + +import com.codeboy.mvc.model.dao.IncorrectNoteDao; +import com.codeboy.mvc.model.responseDto.ApiResponse; +import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; +import org.apache.ibatis.javassist.NotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import java.math.BigInteger; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class IncorrectNoteService { + @Autowired + private IncorrectNoteDao incorrectNoteDao; + + public Long addIncorrectNote(Long memberId, Long problemId, Long userProblemId, Boolean isUserProblem) { + if (!isUserProblem) { + boolean exists = incorrectNoteDao.existsProblemById(problemId); + if (!exists) { + throw new IllegalArgumentException("DB에 존재하지 않는 문제 ID입니다.:" + problemId); + } + } else { + boolean exists = incorrectNoteDao.existsUserProblemById(userProblemId); + if (!exists) { + throw new IllegalArgumentException("DB에 존재하지 않는 유저문제 ID입니다.:" + userProblemId); + } + } + + //TODO : DB에 존재하는지 검증하는 로직 필요 + if (memberId == null) { + throw new IllegalArgumentException("유효하지 않은 회원 ID입니다.: " + memberId); + } + if ((!isUserProblem && (problemId == null || userProblemId != null)) || + (isUserProblem && (problemId != null || userProblemId == null))) { + throw new IllegalArgumentException("유효하지 않은 문제 ID 입니다.:" ); + } + + + Map params = new HashMap<>(); + params.put("memberId", memberId); + params.put("problemId", problemId); + params.put("userProblemId", userProblemId); + params.put("isUserProblem", isUserProblem); + + params.put("incorrectNoteId", null); + + incorrectNoteDao.insertIncorrectProblem(params); + + BigInteger id = (BigInteger) params.get("incorrectNoteId"); + return id != null ? id.longValue() : null; + + } + + public List getIncorrectNoteList(Long memberId) throws NotFoundException { + //TODO : DB에 존재하는지 검증하는 로직 +// if (memberId == null || !memberDao.existsById(memberId)) { +// throw new IllegalArgumentException("유효하지 않은 회원 ID입니다."); +// } + if (memberId == null) { + throw new IllegalArgumentException("유효하지 않은 회원 ID입니다."); + } + + List list = incorrectNoteDao.selectIncorrectProblems(memberId); + + if (list == null || list.isEmpty()) { + throw new NotFoundException("오답노트를 조회할 수 없습니다."); + } + + return list; + } + + public void deleteIncorrectNote(long incorrectNoteId) { + boolean exists = incorrectNoteDao.existsIncorrectNoteById(incorrectNoteId); + if (!exists) { + throw new IllegalArgumentException("DB에 존재하지 않는 오답노트ID 입니다.: " + incorrectNoteId); + } + + incorrectNoteDao.deleteIncorrectProblem(incorrectNoteId); + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java deleted file mode 100644 index 74d629c..0000000 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteServiceImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.codeboy.mvc.model.service; - -import com.codeboy.common.ProblemType; -import com.codeboy.mvc.model.dao.IncorrectNoteDao; -import com.codeboy.mvc.model.dto.Problem; -import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Service -public class IncorrectNoteServiceImpl{ - @Autowired - private IncorrectNoteDao incorrectNoteDao; - - public Long addIncorrectNote(Long memberId, Long problemId, Long userProblemId, ProblemType problemType) { - Map params = new HashMap<>(); - params.put("memberId", memberId); - params.put("problemId", problemId); - params.put("userProblemId", userProblemId); - params.put("problemType", problemType); - - return incorrectNoteDao.insertIncorrectProblem(params); - } - - public List getIncorrectNoteList(long memberId) { - return incorrectNoteDao.selectIncorrectProblems(memberId); - } - - public boolean deleteIncorrectNote(long incorrectNoteId) { - int deleted = incorrectNoteDao.deleteIncorrectProblem(incorrectNoteId); - return deleted > 0; - } -} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java index 281d61c..ca3fe50 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java @@ -2,28 +2,51 @@ import java.util.List; -import com.codeboy.mvc.model.dto.Member; -import org.springframework.stereotype.Service; +import org.springframework.beans.factory.annotation.Autowired; +import com.codeboy.mvc.model.dao.QuizRoomDao; import com.codeboy.mvc.model.dto.QuizRoom; import com.codeboy.mvc.model.dto.QuizRoomMember; +import org.springframework.stereotype.Service; + @Service -public interface QuizRoomService { +public class QuizRoomService{ + @Autowired + private QuizRoomDao quizRoomDao; + + + public List getQuizRoomList() { + return quizRoomDao.selectAllQuizRoom(); + } + + public List getOneQuizRoomMember(long roomId) { + return quizRoomDao.selectOneQuizRoom( roomId); - //퀴즈방 전체 조회 - public List getQuizRoomList(); + } - //퀴즈 방 만들기 -> 생성된 퀴즈방 id를 return - public long createQuizRoom(); + public long createQuizRoom() { + QuizRoom room = new QuizRoom(); + quizRoomDao.insertQuizRoom(room); + //생성된 채팅방 id 리턴 + return room.getRoomId(); - public List getOneQuizRoomMember(long roomId); + } - //참가자 채팅방 입장 - public boolean joinQuizRoom(QuizRoomMember quizRoomMember); + public boolean joinQuizRoom(QuizRoomMember quizRoomMember) { + int rowsAffected = quizRoomDao.insertMemberToQuizRoom(quizRoomMember); + if (rowsAffected > 0) { + return true; + } else { + return false; + } - //퀴즈룸 삭제 - public boolean deleteQuizRoom(long roomId); + } - //방 존재 여부 - public boolean existsQuizRoom(long roomId); + public boolean deleteQuizRoom(long roomId) { + boolean ok = quizRoomDao.deleteQuizRoom(roomId); + return ok; + } + public boolean existsQuizRoom(long roomId){ + return quizRoomDao.existsQuizRoom(roomId) > 0; + } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java deleted file mode 100644 index 2ae9b35..0000000 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomServiceImpl.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.codeboy.mvc.model.service; - -import java.util.List; - -import com.codeboy.mvc.model.dto.Member; -import org.springframework.beans.factory.annotation.Autowired; - -import com.codeboy.mvc.model.dao.QuizRoomDao; -import com.codeboy.mvc.model.dto.QuizRoom; -import com.codeboy.mvc.model.dto.QuizRoomMember; -import org.springframework.stereotype.Service; - -@Service -public class QuizRoomServiceImpl implements QuizRoomService{ - @Autowired - private QuizRoomDao quizRoomDao; - - - @Override - public List getQuizRoomList() { - return quizRoomDao.selectAllQuizRoom(); - } - - @Override - public List getOneQuizRoomMember(long roomId) { - return quizRoomDao.selectOneQuizRoom( roomId); - - } - - @Override - public long createQuizRoom() { - QuizRoom room = new QuizRoom(); - quizRoomDao.insertQuizRoom(room); - //생성된 채팅방 id 리턴 - return room.getRoomId(); - - } - - @Override - public boolean joinQuizRoom(QuizRoomMember quizRoomMember) { - int rowsAffected = quizRoomDao.insertMemberToQuizRoom(quizRoomMember); - if (rowsAffected > 0) { - return true; - } else { - return false; - } - - } - - @Override - public boolean deleteQuizRoom(long roomId) { - boolean ok = quizRoomDao.deleteQuizRoom(roomId); - return ok; - } - @Override - public boolean existsQuizRoom(long roomId){ - return quizRoomDao.existsQuizRoom(roomId) > 0; - } -} diff --git a/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml b/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml index 498075e..7685bed 100644 --- a/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/IncorrectNoteMapper.xml @@ -17,7 +17,7 @@ FROM incorrect_note inote JOIN problem p ON inote.problem_id = p.problem_id WHERE inote.member_id = #{memberId} - AND inote.problem_type = 'PROBLEM' + AND inote.is_user_problem = 0 ) UNION ALL (SELECT inote.incorrect_note_id, @@ -29,11 +29,29 @@ u.answer, u.category FROM incorrect_note inote - JOIN user_problem u ON inote.problem_id = u.user_problem_id + JOIN user_problem u ON inote.user_problem_id = u.user_problem_id WHERE inote.member_id = #{memberId} - AND inote.problem_type = 'USER_PROBLEM' + AND inote.is_user_problem = 1 ) + + + + + + DELETE FROM incorrect_note @@ -41,11 +59,9 @@ - - INSERT INTO incorrect_note (member_id, problem_id, user_problem_id, problem_type) - VALUES (#{memberId}, #{problemId}, #{userProblemId}, #{problemType}) - - + + INSERT INTO incorrect_note (member_id, problem_id, user_problem_id, is_user_problem) + VALUES (#{memberId}, #{problemId}, #{userProblemId}, #{isUserProblem}) \ No newline at end of file From b52b42cf74eec6360926443226aa71919b89a1c6 Mon Sep 17 00:00:00 2001 From: mingeung Date: Thu, 27 Nov 2025 16:29:08 +0900 Subject: [PATCH 21/61] =?UTF-8?q?feat:=20=ED=80=B4=EC=A6=88=EB=B0=A9=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20Service=EC=97=90=EC=84=9C=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mvc/controller/QuizRoomController.java | 154 +++++++----------- .../mvc/model/dao/IncorrectNoteDao.java | 2 +- .../codeboy/mvc/model/dao/QuizRoomDao.java | 12 +- .../codeboy/mvc/model/dto/QuizRoomMember.java | 12 +- .../requestDto/CreateQuizRoomRequest.java | 12 -- .../model/service/IncorrectNoteService.java | 8 - .../mvc/model/service/QuizRoomService.java | 57 +++++-- .../main/resources/mappers/QuizRoomMapper.xml | 2 +- 8 files changed, 108 insertions(+), 151 deletions(-) delete mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CreateQuizRoomRequest.java diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java index 4be9763..fcda38f 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java @@ -1,146 +1,106 @@ package com.codeboy.mvc.controller; + import com.codeboy.mvc.model.dto.*; -import com.codeboy.mvc.model.requestDto.CreateQuizRoomRequest; import com.codeboy.mvc.model.requestDto.JoinQuizRoomRequest; import com.codeboy.mvc.model.responseDto.ApiResponse; -import com.codeboy.mvc.model.service.IncorrectNoteService; import com.codeboy.mvc.model.service.QuizRoomService; -import jakarta.annotation.PostConstruct; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import javax.sql.DataSource; import java.util.List; @RestController @RequestMapping("/api/quiz-room") - public class QuizRoomController { - - private final QuizRoomService quizRoomService; - public QuizRoomController(QuizRoomService quizRoomService){ + public QuizRoomController(QuizRoomService quizRoomService) { this.quizRoomService = quizRoomService; } - - //호스트 - 퀴즈방 만들기 - @PostMapping("/create") + @PostMapping("/create") //TODO : 로그인 구현되면 memberId를 requestBody로 넘기지 말고 세션에서 가져오도록 하기 - public ResponseEntity> createQuizRoom(@RequestBody CreateQuizRoomRequest request) { - long memberId = request.getMemberId(); - - //1. memberId가 유효한지 체크 - //TODO : membertable에서 해당 멤버가 있는지 확인하는 조건 추가 - if (memberId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "멤버ID가 유효하지 않습니다.")); - } - - //2. 새로운 채팅방 생성하기 - long quizRoomId = quizRoomService.createQuizRoom(); - if (quizRoomId <= 0) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.failure(HttpStatus.NOT_FOUND, "새로운 퀴즈방 생성에 실패했습니다")); + public ResponseEntity> createQuizRoom() { + try { + //새로운 채팅방 생성하기 + long quizRoomId = quizRoomService.createQuizRoom(); + //3. QuizRoomMember 객체 생성 + Long memberId = 1L; + QuizRoomMember quizRoomMember = new QuizRoomMember(); + //4. setter로 객체 만들기 + quizRoomMember.setMemberId(memberId); + quizRoomMember.setRoomId(quizRoomId); + quizRoomMember.setIsHost(true); + + //5. 채팅방에 넣기 + quizRoomService.joinQuizRoom(quizRoomMember); + return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(HttpStatus.CREATED, "퀴즈방이 성공적으로 생성되었습니다.", quizRoomId)); + + } catch (IllegalStateException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); } - //3. QuizRoomMember 객체 생성 - QuizRoomMember quizRoomMember = new QuizRoomMember(); - //4. setter로 객체 만들기 - quizRoomMember.setMemberId(memberId); - quizRoomMember.setRoomId(quizRoomId); - quizRoomMember.setIsHost(true); - - //5. 채팅방에 넣기 - boolean isOk = quizRoomService.joinQuizRoom(quizRoomMember); - - if (!isOk) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.failure(HttpStatus.NOT_FOUND, "호스트를 퀴즈방에 넣는 과정이 실패했습니다.")); - } - return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(HttpStatus.CREATED, "퀴즈방이 성공적으로 생성되었습니다.", quizRoomId)); - } - - //채팅방 참여하기 - @PostMapping("/join") + } + + //채팅방 참여하기 + @PostMapping("/join") //TODO : 로그인 구현되면 memberId를 requestBody로 넘기지 말고 세션에서 가져오도록 하기 - public ResponseEntity> joinQuizRoom(@RequestBody JoinQuizRoomRequest request) { - long memberId = request.getMemberId(); + public ResponseEntity> joinQuizRoom(@RequestBody JoinQuizRoomRequest request) { + long memberId = request.getMemberId(); long roomId = request.getRoomId(); - //TODO : 멤버 ID가 DB에 있는지 확인하는 과정 - if (memberId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "멤버ID가 유효하지 않습니다.")); - } - //TODO : 채팅방 인원이 초과되었는지 확인하는 메서드 추가 - //퀴즈방 기본 검증 - if (roomId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "퀴즈방ID가 유효하지 않습니다.")); + try { + //QuizRoomMember 생성 + QuizRoomMember quizRoomMember = new QuizRoomMember(); + quizRoomMember.setIsHost(false); + quizRoomMember.setMemberId(memberId); + quizRoomMember.setRoomId(roomId); + + //채팅방에 참가 + quizRoomService.joinQuizRoom(quizRoomMember); + return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(HttpStatus.CREATED, "퀴즈방 입장에 성공하였습니다.")); + + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); } - //퀴즈방이 존재하는지 확인 - boolean roomExists = quizRoomService.existsQuizRoom(roomId); - if (!roomExists) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.failure(HttpStatus.NOT_FOUND, "존재하지 않는 퀴즈방입니다.")); - - - } - //QuizRoomMember 생성 - QuizRoomMember quizRoomMember = new QuizRoomMember(); - quizRoomMember.setIsHost(false); - quizRoomMember.setMemberId(memberId); - quizRoomMember.setRoomId(roomId); - - //채팅방에 넣기 - boolean isOk = quizRoomService.joinQuizRoom(quizRoomMember); - - if (!isOk) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.failure(HttpStatus.NOT_FOUND, "퀴즈방 입장에 실패하였습니다.")); - } - return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(HttpStatus.CREATED, "퀴즈방 입장에 성공하였습니다.")); } //채팅방 목록 보여주기 @GetMapping public ResponseEntity>> getQuizRoomList() { + try { List quizRooms = quizRoomService.getQuizRoomList(); - if (quizRooms == null) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "퀴즈방 정보를 가져오지 못했습니다")); - } - else if (quizRooms.isEmpty()) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "생성된 퀴즈방이 없습니다.")); - } return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "퀴즈방 목록 조회 성공", quizRooms)); - } + } catch (IllegalStateException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } + } - //현재 참가자 목록 보여주기 + //현재 참가자 목록 보여주기 @GetMapping("/{roomId}/member") public ResponseEntity>> getQuizRoomMembers(@PathVariable long roomId) { - if (roomId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "퀴즈방 ID가 유효하지 않습니다.")); - } - + try { List memberList = quizRoomService.getOneQuizRoomMember(roomId); //TODO : member API 와 연결해서 참가 중인 멤버 닉네임을 보여주도록? - if (!memberList.isEmpty()) { return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "멤버 리스트를 반환합니다.", memberList)); - } - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.failure(HttpStatus.NOT_FOUND, "참가자가 없습니다.")); + } catch (IllegalStateException | IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } } - //채팅방 삭제하기 + //채팅방 삭제하기 @DeleteMapping("/{roomId}") public ResponseEntity> deleteQuizRoom(@PathVariable long roomId) { - if (roomId <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "퀴즈방 ID가 유효하지 않습니다.")); - } - boolean isOk = quizRoomService.deleteQuizRoom(roomId); - if (!isOk) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "퀴즈방 삭제에 실패했습니다.")); + try { + quizRoomService.deleteQuizRoom(roomId); + return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "채팅방이 성공적으로 삭제되었습니다.")); + + } catch (IllegalStateException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); } - return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "성공적으로 퀴즈방이 삭제되었습니다.")); } - } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java index 0baf64e..33b999b 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java @@ -18,7 +18,7 @@ public interface IncorrectNoteDao { public int deleteIncorrectProblem(Long incorrectNoteId); //오답노트에 문제 추가 - public Long insertIncorrectProblem(Map params); + public void insertIncorrectProblem(Map params); //문제 존재 여부 체크 boolean existsProblemById(Long problemId); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java index 00c705c..bfbded2 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java @@ -8,29 +8,23 @@ @Mapper public interface QuizRoomDao { - //quiz_room 테이블. 퀴즈룸 생성. 생성된 퀴즈룸 id 반환 public void insertQuizRoom(QuizRoom room); //quiz_room_member 테이블에 값 넣기 (퀴즈방 입장) - 참가자/호스트 public int insertMemberToQuizRoom(QuizRoomMember quizRoomMember); - - //모든 퀴즈룸 조회하기 public List selectAllQuizRoom(); - - //하나의 퀴즈룸 조회(참가 멤버확인) - public List selectOneQuizRoom(long roomId); + public List selectOneQuizRoom(Long roomId); //퀴즈룸 수정 - //퀴즈룸 삭제 - public boolean deleteQuizRoom(long roomId); + public boolean deleteQuizRoom(Long roomId); //퀴즈룸 존재하는지 확인 - public int existsQuizRoom(long roomId); + public boolean existsQuizRoom(Long roomId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/QuizRoomMember.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/QuizRoomMember.java index 6a0df26..8079a50 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/QuizRoomMember.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/QuizRoomMember.java @@ -12,23 +12,23 @@ @Setter @Schema(description="회원 퀴즈방 중간 DTO") public class QuizRoomMember { - private long quizRoomMemberId; - private long memberId; - private long roomId; + private Long quizRoomMemberId; + private Long memberId; + private Long roomId; private Boolean isHost; - public long getQuizRoomMemberId() { + public Long getQuizRoomMemberId() { return quizRoomMemberId; } public void setQuizRoomMemberId(long quizRoomMemberId) { this.quizRoomMemberId = quizRoomMemberId; } - public long getMemberId() { + public Long getMemberId() { return memberId; } public void setMemberId(long memberId) { this.memberId = memberId; } - public long getRoomId() { + public Long getRoomId() { return roomId; } public void setRoomId(long roomId) { diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CreateQuizRoomRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CreateQuizRoomRequest.java deleted file mode 100644 index 28c816f..0000000 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/CreateQuizRoomRequest.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.codeboy.mvc.model.requestDto; - -import lombok.*; - -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -@ToString -public class CreateQuizRoomRequest { - private long memberId; -} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java index 50ec94b..460a9fa 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java @@ -1,14 +1,10 @@ package com.codeboy.mvc.model.service; import com.codeboy.mvc.model.dao.IncorrectNoteDao; -import com.codeboy.mvc.model.responseDto.ApiResponse; import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; import org.apache.ibatis.javassist.NotFoundException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; - import java.math.BigInteger; import java.util.HashMap; import java.util.List; @@ -41,7 +37,6 @@ public Long addIncorrectNote(Long memberId, Long problemId, Long userProblemId, throw new IllegalArgumentException("유효하지 않은 문제 ID 입니다.:" ); } - Map params = new HashMap<>(); params.put("memberId", memberId); params.put("problemId", problemId); @@ -65,13 +60,11 @@ public List getIncorrectNoteList(Long memberId) throws No if (memberId == null) { throw new IllegalArgumentException("유효하지 않은 회원 ID입니다."); } - List list = incorrectNoteDao.selectIncorrectProblems(memberId); if (list == null || list.isEmpty()) { throw new NotFoundException("오답노트를 조회할 수 없습니다."); } - return list; } @@ -80,7 +73,6 @@ public void deleteIncorrectNote(long incorrectNoteId) { if (!exists) { throw new IllegalArgumentException("DB에 존재하지 않는 오답노트ID 입니다.: " + incorrectNoteId); } - incorrectNoteDao.deleteIncorrectProblem(incorrectNoteId); } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java index ca3fe50..204bd28 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java @@ -14,39 +14,62 @@ public class QuizRoomService{ @Autowired private QuizRoomDao quizRoomDao; - public List getQuizRoomList() { - return quizRoomDao.selectAllQuizRoom(); + List quizRooms = quizRoomDao.selectAllQuizRoom(); + if (quizRooms == null) { + throw new IllegalStateException("퀴즈방 정보를 가져오지 못했습니다"); + } + return quizRooms; } public List getOneQuizRoomMember(long roomId) { - return quizRoomDao.selectOneQuizRoom( roomId); + validateRoomId(roomId); + + List memberList = quizRoomDao.selectOneQuizRoom( roomId); + if (!memberList.isEmpty()) { + throw new IllegalStateException("퀴즈방에 참가자가 없습니다."); + } + return memberList; } public long createQuizRoom() { QuizRoom room = new QuizRoom(); quizRoomDao.insertQuizRoom(room); - //생성된 채팅방 id 리턴 - return room.getRoomId(); + Long roomId = room.getRoomId(); + + validateRoomId(roomId); + return roomId; } - public boolean joinQuizRoom(QuizRoomMember quizRoomMember) { - int rowsAffected = quizRoomDao.insertMemberToQuizRoom(quizRoomMember); - if (rowsAffected > 0) { - return true; - } else { - return false; - } + public void joinQuizRoom(QuizRoomMember quizRoomMember) { + Long memberId = quizRoomMember.getMemberId(); + Long roomId = quizRoomMember.getRoomId(); + validateRoomId(roomId); + //멤버 id가 실제로 존재하는지 확인 + if (memberId == null) { + throw new IllegalArgumentException("멤버 ID가 유효하지 않습니다. :" ); + } + //TODO : 채팅방 참여 인원이 초과되었는지 검증하는 로직 추가 + int rowAffected = quizRoomDao.insertMemberToQuizRoom(quizRoomMember); + if (rowAffected <= 0) { + throw new IllegalStateException("퀴즈방 입장에 실패하였습니다."); + } } - public boolean deleteQuizRoom(long roomId) { - boolean ok = quizRoomDao.deleteQuizRoom(roomId); - return ok; + public void deleteQuizRoom(long roomId) { + validateRoomId(roomId); + boolean deleted = quizRoomDao.deleteQuizRoom(roomId); + if (!deleted) { + throw new IllegalStateException("퀴즈방 삭제에 실패했습니다."); + } } - public boolean existsQuizRoom(long roomId){ - return quizRoomDao.existsQuizRoom(roomId) > 0; + + private void validateRoomId(Long roomId) { + if (roomId == null || roomId <= 0 || !quizRoomDao.existsQuizRoom(roomId)) { + throw new IllegalArgumentException("퀴즈방 ID가 유효하지 않습니다. : " + roomId); + } } } diff --git a/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml b/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml index a3c6a37..87930aa 100644 --- a/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml @@ -48,7 +48,7 @@ From fd0b1ae64d58bfde3ab8ffa11d272b1985912883 Mon Sep 17 00:00:00 2001 From: mingeung Date: Thu, 27 Nov 2025 17:53:17 +0900 Subject: [PATCH 22/61] =?UTF-8?q?feat:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EB=A9=A4=EB=B2=84=20=EC=A4=91=EB=B3=B5=20=EC=9E=85=EC=9E=A5=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8=20=EB=A1=9C=EC=A7=81.=20=ED=80=B4=EC=A6=88?= =?UTF-8?q?=EB=B0=A9=EC=97=90=20=EC=9E=88=EB=8A=94=20=EB=A9=A4=EB=B2=84=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20dto=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mvc/controller/QuizRoomController.java | 13 +++++++------ .../codeboy/mvc/model/dao/QuizRoomDao.java | 11 ++++++++--- .../getQuizRoomMembersResponse.java | 13 +++++++++++++ .../mvc/model/service/QuizRoomService.java | 17 ++++++++++++++--- .../main/resources/mappers/QuizRoomMapper.xml | 19 ++++++++++++++----- 5 files changed, 56 insertions(+), 17 deletions(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/getQuizRoomMembersResponse.java diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java index fcda38f..4a3c7aa 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java @@ -3,6 +3,7 @@ import com.codeboy.mvc.model.dto.*; import com.codeboy.mvc.model.requestDto.JoinQuizRoomRequest; import com.codeboy.mvc.model.responseDto.ApiResponse; +import com.codeboy.mvc.model.responseDto.getQuizRoomMembersResponse; import com.codeboy.mvc.model.service.QuizRoomService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -20,14 +21,15 @@ public QuizRoomController(QuizRoomService quizRoomService) { } //호스트 - 퀴즈방 만들기 - @PostMapping("/create") + //TODO : 테스트용으로 memberId를 PathVariable로 넘김 + @PostMapping("/create/{memberId}") //TODO : 로그인 구현되면 memberId를 requestBody로 넘기지 말고 세션에서 가져오도록 하기 - public ResponseEntity> createQuizRoom() { + public ResponseEntity> createQuizRoom(@PathVariable long memberId) { try { //새로운 채팅방 생성하기 long quizRoomId = quizRoomService.createQuizRoom(); //3. QuizRoomMember 객체 생성 - Long memberId = 1L; +// Long memberId = 1L; QuizRoomMember quizRoomMember = new QuizRoomMember(); //4. setter로 객체 만들기 quizRoomMember.setMemberId(memberId); @@ -80,11 +82,10 @@ public ResponseEntity>> getQuizRoomList() { //현재 참가자 목록 보여주기 @GetMapping("/{roomId}/member") - public ResponseEntity>> getQuizRoomMembers(@PathVariable long roomId) { + public ResponseEntity>> getQuizRoomMembers(@PathVariable long roomId) { try { - List memberList = quizRoomService.getOneQuizRoomMember(roomId); + List memberList = quizRoomService.getOneQuizRoomMember(roomId); - //TODO : member API 와 연결해서 참가 중인 멤버 닉네임을 보여주도록? return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "멤버 리스트를 반환합니다.", memberList)); } catch (IllegalStateException | IllegalArgumentException e) { diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java index bfbded2..7ba8f08 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java @@ -4,6 +4,7 @@ import com.codeboy.mvc.model.dto.QuizRoom; import com.codeboy.mvc.model.dto.QuizRoomMember; +import com.codeboy.mvc.model.responseDto.getQuizRoomMembersResponse; import org.apache.ibatis.annotations.Mapper; @Mapper @@ -17,14 +18,18 @@ public interface QuizRoomDao { public List selectAllQuizRoom(); //하나의 퀴즈룸 조회(참가 멤버확인) - public List selectOneQuizRoom(Long roomId); + public List selectOneQuizRoom(Long roomId); //퀴즈룸 수정 - //퀴즈룸 삭제 + //TODO : 지금은 멤버가 전체 퀴즈방 테이블에 중복으로 들어가면 에러 터짐 + //TODO : 채팅방이 끝나면 바로 삭제하는 로직 만들어야 함. + public boolean deleteQuizRoom(Long roomId); //퀴즈룸 존재하는지 확인 - public boolean existsQuizRoom(Long roomId); + public int existsQuizRoom(Long roomId); + //퀴즈룸에 특정 멤버가 있는지 확인 + public int isDuplicatedMember(Long memberId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/getQuizRoomMembersResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/getQuizRoomMembersResponse.java new file mode 100644 index 0000000..7825274 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/getQuizRoomMembersResponse.java @@ -0,0 +1,13 @@ +package com.codeboy.mvc.model.responseDto; + +import lombok.*; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Setter +public class getQuizRoomMembersResponse { + private Long memberId; + private String nickname; +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java index 204bd28..02cedaa 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java @@ -2,6 +2,7 @@ import java.util.List; +import com.codeboy.mvc.model.responseDto.getQuizRoomMembersResponse; import org.springframework.beans.factory.annotation.Autowired; import com.codeboy.mvc.model.dao.QuizRoomDao; @@ -22,10 +23,10 @@ public List getQuizRoomList() { return quizRooms; } - public List getOneQuizRoomMember(long roomId) { + public List getOneQuizRoomMember(long roomId) { validateRoomId(roomId); - List memberList = quizRoomDao.selectOneQuizRoom( roomId); + List memberList = quizRoomDao.selectOneQuizRoom(roomId); if (!memberList.isEmpty()) { throw new IllegalStateException("퀴즈방에 참가자가 없습니다."); @@ -47,6 +48,7 @@ public void joinQuizRoom(QuizRoomMember quizRoomMember) { Long memberId = quizRoomMember.getMemberId(); Long roomId = quizRoomMember.getRoomId(); validateRoomId(roomId); + memberDuplicateCheck(memberId); //멤버 id가 실제로 존재하는지 확인 if (memberId == null) { @@ -68,8 +70,17 @@ public void deleteQuizRoom(long roomId) { } private void validateRoomId(Long roomId) { - if (roomId == null || roomId <= 0 || !quizRoomDao.existsQuizRoom(roomId)) { + boolean existRoom = quizRoomDao.existsQuizRoom(roomId) > 0; + if (roomId == null || roomId <= 0 || !existRoom) { throw new IllegalArgumentException("퀴즈방 ID가 유효하지 않습니다. : " + roomId); } } + + private void memberDuplicateCheck(Long memberId) { + boolean duplicated = quizRoomDao.isDuplicatedMember(memberId) > 0; + if (duplicated) { + throw new IllegalArgumentException("한 멤버는 하나의 채팅방에만 들어갈 수 있습니다."); + } + } + } diff --git a/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml b/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml index 87930aa..0a75a1e 100644 --- a/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml @@ -14,7 +14,6 @@ VALUES(); - @@ -48,10 +50,17 @@ + + + \ No newline at end of file From b67cac692a88daf0bfa5fa8fee22a2515d0b9ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=A4=80=ED=98=95?= Date: Thu, 27 Nov 2025 17:59:05 +0900 Subject: [PATCH 23/61] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=EC=A0=9C?= =?UTF-8?q?=EC=9E=91=20=EB=AC=B8=EC=A0=9C,=20=EC=84=B8=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mvc/controller/CommentController.java | 3 +- .../com/codeboy/mvc/model/dao/CommentDao.java | 10 ++-- .../com/codeboy/mvc/model/dao/ScoreDao.java | 2 +- .../mvc/model/dao/UserIncorrectNoteDao.java | 17 ------- .../codeboy/mvc/model/dao/UserProblemDao.java | 19 ++++--- .../mvc/model/dao/UserProblemSetDao.java | 15 +++++- .../mvc/model/service/CommentService.java | 16 +++--- .../mvc/model/service/CommentServiceImpl.java | 10 ++-- .../resources/mappers/UserProblemMapper.xml | 51 +++++++++++++++++++ .../mappers/UserProblemSetMapper.xml | 27 +++++++++- 10 files changed, 122 insertions(+), 48 deletions(-) delete mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.java create mode 100644 codeBoy_backend/src/main/resources/mappers/UserProblemMapper.xml diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java index 1d7198d..2c1e2bc 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java @@ -22,10 +22,11 @@ import com.codeboy.mvc.model.service.CommentService; @RestController -@RequestMapping("/api/user-problem-sets") +@RequestMapping("/api/comments") public class CommentController { private final CommentService commentService; + @Autowired public CommentController(CommentService commentService) { this.commentService = commentService; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java index bdd2b8c..1f75116 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/CommentDao.java @@ -8,18 +8,18 @@ @Mapper public interface CommentDao { - public List selectCommentsByuserProblemSetId(long userProblemSetId); + public List selectCommentsByuserProblemSetId(Long userProblemSetId); //유저문제세트 id에다가 댓글을 달아야하므로 long userProblemSetId으로 지정 - public int insertComment(long userProblemSetId, Comment comment); + public int insertComment(Long userProblemSetId, Comment comment); //조회된 댓글의 id를 가져와서 수정하고 삭제함. - public int updateComment(long commentId, Comment comment); + public int updateComment(Long commentId, Comment comment); //조회된 댓글의 id를 가져와서 수정하고 삭제함. - public int deleteComment(long commentId); + public int deleteComment(Long commentId); //댓글아이디로 댓글 작성자의 아이디를 가져옴 - public Long selectCommentOwnerId(long commentId); + public Long selectCommentOwnerId(Long commentId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ScoreDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ScoreDao.java index 8245fd0..f61f3ab 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ScoreDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ScoreDao.java @@ -12,7 +12,7 @@ public interface ScoreDao { public List selectAllUserScore(); //한 멤버의 스코어 조회 - public int selectOneUserScore(int memberId); + public int selectOneUserScore(Long memberId); //멤버 스코어 업데이트 public void updateUserScore(UserScore userScore); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.java deleted file mode 100644 index b996c4b..0000000 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.codeboy.mvc.model.dao; - -import java.util.List; - -import com.codeboy.mvc.model.dto.UserProblem; - -public interface UserIncorrectNoteDao { - - //유저의 아이디로 유저가 틀린 문제들의 모음을 조회 - public List selectUserIncorrectProblems(long memberId); - - //유저가 자신의 오답노트 안에서 문제를 삭제 - public void deleteUserIncorrectProblem(long memberId, long userProblemId); - - //(중간자 테이블)오답노트에 문제 추가 - public void insertUserIncorrectProblem(long memberId, long userProblemId); -} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemDao.java index 9730bef..de918f4 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemDao.java @@ -7,18 +7,17 @@ public interface UserProblemDao extends ProblemDao{ - //문제세트 조회 - public List selectUserProblem(Category category); - //문제 생성하기 - public void insertUserProblem(UserProblem userProblem); + //유저제작 문제풀이 페이지에서 문제세트를 선택했을때, 그 문제세트에 속한문제들 조회 + List selectProblemsByUserProblemSetId(Long userProblemSetId); - //문제 세트 만들기 - public void insertUserProblemSet(List userProblemList); + //문제 생성 시 문제세트를 등록함과 동시에 문제들을 전부 user_problem 테이블에 넣기 + int insertUserProblemList(List userProblems); - //문제 수정 - public void updateUserProblem(UserProblem userProblem); + //제작자 본인이 자신의 문제들을 수정하는 로직 + int updateUserProblem(UserProblem userProblem); + + //제작자 본인이 자신의 문제를 삭제하는 로직 + int deleteUserProblem(Long userProblemId); - //문제 삭제 - public int deleteUserProblem(int id); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java index 14bc58d..f08f709 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java @@ -1,12 +1,25 @@ package com.codeboy.mvc.model.dao; import com.codeboy.mvc.model.dto.Problem; +import com.codeboy.mvc.model.dto.UserProblem; +import com.codeboy.mvc.model.dto.UserProblemSet; import java.util.List; public interface UserProblemSetDao { - public List selectProblemsByUserProblemSetId(long userProblemSetId); + //다른 사용자들이 만든 유저제작 문제세트들을 모두 조회 + List selectUserProblemSets(); + + //마이페이지에서 자신이 제작한 문제세트 조회 + List selectUserProblemSetByMemberId(Long memberId); + + //문제 세트 등록 memberId = 문제 제작자만 넘겨주고 문제들은 problemDao에서 insertUserProblem으로 넣음 (마이페이지에서 생성) + int insertUserProblemSet(Long memberId); + + // 문제세트 삭제 (마이페이지에서 삭제) + int deleteUserProblemSetById(long userProblemSetId); + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java index c96e672..d1b02dd 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentService.java @@ -5,16 +5,20 @@ import com.codeboy.mvc.model.dto.Comment; public interface CommentService { - //유저제작 문제 세트Id로 조회 - public List getAllCommentsById(long userProblemSetId); + /** + * 유저제작 문제 세트Id로 조회 + * @param userProblemSetId + * @return + */ + public List getAllCommentsById(Long userProblemSetId); //유저제작 문제 세트Id로 조회후 해당 세트에 댓글 작성 - public int addComment(long userProblemSetId, Comment comment); + public int addComment(Long userProblemSetId, Comment comment); // - public int updateComment(long commentId, Comment comment); + public int updateComment(Long commentId, Comment comment); // - public int deleteComment(long commentId); + public int deleteComment(Long commentId); - public Long getCommentOwnerId(long commentId); + public Long getCommentOwnerId(Long commentId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java index 44ae5be..2d1dedd 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CommentServiceImpl.java @@ -22,12 +22,12 @@ public CommentServiceImpl(CommentDao commentDao) { // 유저제작 문제 세트Id로 조회 @Override - public List getAllCommentsById(long userProblemSetId) { + public List getAllCommentsById(Long userProblemSetId) { return commentDao.selectCommentsByuserProblemSetId(userProblemSetId); } @Override - public int addComment(long userProblemSetId, Comment comment ) { + public int addComment(Long userProblemSetId, Comment comment ) { return commentDao.insertComment(userProblemSetId, comment); } @@ -35,7 +35,7 @@ public int addComment(long userProblemSetId, Comment comment ) { @Override - public int updateComment(long commentId, Comment comment) { + public int updateComment(Long commentId, Comment comment) { return commentDao.updateComment(commentId, comment); } @@ -43,14 +43,14 @@ public int updateComment(long commentId, Comment comment) { @Override - public int deleteComment(long commentId) { + public int deleteComment(Long commentId) { return commentDao.deleteComment(commentId); } @Override - public Long getCommentOwnerId(long commentId){ + public Long getCommentOwnerId(Long commentId){ return commentDao.selectCommentOwnerId(commentId); } diff --git a/codeBoy_backend/src/main/resources/mappers/UserProblemMapper.xml b/codeBoy_backend/src/main/resources/mappers/UserProblemMapper.xml new file mode 100644 index 0000000..8d1ff96 --- /dev/null +++ b/codeBoy_backend/src/main/resources/mappers/UserProblemMapper.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + INSERT INTO user_problem + (problem_description, category, choice_1, choice_2, choice_3, choice_4, answer, comment_count, user_problem_set_id) + VALUES + + (#{item.problemDescription}, #{item.category}, #{item.choice1}, #{item.choice2}, #{item.choice3}, #{item.choice4}, #{item.answer}, #{item.commentCount}, #{item.userProblemSetId}) + + + + + + + UPDATE user_problem + SET problem_description = #{problemDescription}, + category = #{category}, + choice_1 = #{choice1}, + choice_2 = #{choice2}, + choice_3 = #{choice3}, + choice_4 = #{choice4}, + answer = #{answer}, + comment_count = #{commentCount}, + WHERE user_problem_id = #{userProblemId} + + + + + DELETE FROM user_problem + WHERE user_problem_id = #{userProblemId} + + + + + + + diff --git a/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml b/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml index c42da7e..fb94fc7 100644 --- a/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml @@ -4,8 +4,31 @@ - - + SELECT * + FROM user_problem_set + + + + + + + INSERT INTO user_problem_set (member_id) + VALUES (#{memberId}) + + + + + DELETE FROM user_problem_set + WHERE id = #{id} + + + + From 2f2f1a972d972b904c11ddca0749e195d49328be Mon Sep 17 00:00:00 2001 From: junhyung8795 Date: Fri, 28 Nov 2025 01:32:00 +0900 Subject: [PATCH 24/61] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=EC=A0=9C?= =?UTF-8?q?=EC=9E=91=EB=AC=B8=EC=A0=9C=EC=99=80=20=EC=9C=A0=EC=A0=80?= =?UTF-8?q?=EC=A0=9C=EC=9E=91=EB=AC=B8=EC=A0=9C=EC=84=B8=ED=8A=B8=EC=9D=98?= =?UTF-8?q?=20Controller,=20Mapper,=20Service,=20ServiceImpl=EC=99=84?= =?UTF-8?q?=EC=84=B1=201.=20=EC=A0=84=EC=B2=B4=EC=A0=81=EC=9C=BC=EB=A1=9C?= =?UTF-8?q?=20url=EC=9D=B4=20=EB=82=9C=EC=9E=A1=ED=95=B4=EC=84=9C=20?= =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=EC=9D=98=20url=EC=A3=BC?= =?UTF-8?q?=EC=86=8C=EA=B0=80=20=ED=94=84=EB=A1=A0=ED=8A=B8=EB=8B=A8?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EA=B4=9C=EC=B0=AE=EC=9D=84=EC=A7=80=20?= =?UTF-8?q?=ED=98=91=EC=9D=98=ED=95=B4=EB=B4=90=EC=95=BC=ED=95=A8=202.=20?= =?UTF-8?q?=ED=8A=B9=ED=9E=88=20=EC=9C=A0=EC=A0=80=EA=B0=80=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=EB=A5=BC=20=EC=A0=9C=EC=9E=91=ED=95=98=EA=B3=A0=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=ED=95=A0=20=EB=95=8C,=20=EC=84=B8=ED=8A=B8?= =?UTF-8?q?=EB=8F=84=20=EB=93=B1=EB=A1=9D=ED=95=98=EA=B3=A0=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=EB=93=A4=EB=8F=84=20=EB=AC=B8=EC=A0=9C=EB=A7=8C=20?= =?UTF-8?q?=EB=94=B0=EB=A1=9C=20=EB=AA=A8=EC=95=84=EB=86=93=EB=8A=94=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=EC=9D=B4=20=EC=9E=88=EC=96=B4?= =?UTF-8?q?=EC=84=9C=20=EB=A7=8C=EC=95=BD=20=EC=9C=A0=EC=A0=80=EA=B0=80=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=EB=A5=BC=20=EB=93=B1=EB=A1=9D=ED=95=9C?= =?UTF-8?q?=EB=8B=A4=EB=A9=B4=20=EC=84=B8=ED=8A=B8=20=EB=93=B1=EB=A1=9D->?= =?UTF-8?q?=20=EB=93=B1=EB=A1=9D=ED=95=9C=20=EA=B2=B0=EA=B3=BC=EB=AC=BC?= =?UTF-8?q?=EB=A1=9C=20set=EC=9D=84=20=EB=A6=AC=EC=8A=A4=ED=8F=B0=EC=8A=A4?= =?UTF-8?q?=EB=B0=94=EB=94=94(ApiResponse)=EC=97=90=20=EB=84=A3=EA=B3=A0?= =?UTF-8?q?=20=EC=9D=B4=20set=EC=95=88=EC=97=90=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=EC=84=B8=ED=8A=B8=20Id=EA=B0=80=20=EB=8B=B4=EA=B2=A8=EC=9E=88?= =?UTF-8?q?=EC=9C=BC=EB=8B=88=20=EC=9D=B4=EA=B1=B8=EB=A1=9C=20=EB=8B=A4?= =?UTF-8?q?=EC=8B=9C=20/api/user-problems/sets/{userProblemSetId}=EB=A1=9C?= =?UTF-8?q?=20Post=EC=9A=94=EC=B2=AD=EC=9D=84=20=EB=B3=B4=EB=82=B4?= =?UTF-8?q?=EC=95=BC=20=EB=AC=B8=EC=A0=9C=EB=93=A4=EB=8F=84=20=EC=95=88?= =?UTF-8?q?=EC=A0=84=ED=95=98=EA=B2=8C=20user=5Fproblem=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=EC=97=90=20=EB=8B=B4=EA=B8=B0=EA=B2=8C=20=EB=90=9C?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mvc/controller/CommentController.java | 4 +- .../mvc/controller/UserProblemController.java | 152 ++++++++++++++++++ .../controller/UserProblemSetController.java | 135 ++++++++++++++++ .../codeboy/mvc/model/dao/UserProblemDao.java | 3 +- .../mvc/model/dao/UserProblemSetDao.java | 6 +- .../codeboy/mvc/model/dto/UserProblem.java | 4 +- .../codeboy/mvc/model/dto/UserProblemSet.java | 4 +- .../mvc/model/service/UserProblemService.java | 13 +- .../model/service/UserProblemServiceImpl.java | 46 ++++++ .../model/service/UserProblemSetService.java | 15 ++ .../service/UserProblemSetServiceImpl.java | 44 +++++ .../resources/mappers/UserProblemMapper.xml | 2 +- .../mappers/UserProblemSetMapper.xml | 9 +- 13 files changed, 422 insertions(+), 15 deletions(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemServiceImpl.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetService.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetServiceImpl.java diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java index 2c1e2bc..2da87f0 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java @@ -59,8 +59,8 @@ public ResponseEntity> addComment(@PathVariable long userProbl int result = commentService.addComment(userProblemSetId, comment); if (result == 0) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "댓글 추가 실패")); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "잘못된 요청. 댓글 추가 실패")); } return ResponseEntity.status(HttpStatus.CREATED) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java new file mode 100644 index 0000000..8b00f96 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java @@ -0,0 +1,152 @@ +package com.codeboy.mvc.controller; + +import com.codeboy.mvc.model.dto.UserProblem; +import com.codeboy.mvc.model.responseDto.ApiResponse; // 실제 패키지에 맞게 수정 +import com.codeboy.mvc.model.service.UserProblemService; +import jakarta.servlet.http.HttpSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/user-problems") +public class UserProblemController { + + + private final UserProblemService userProblemService; + + public UserProblemController(UserProblemService userProblemService) { + this.userProblemService = userProblemService; + } + + // 특정 문제세트 안의 모든 문제 조회 + @GetMapping("/sets/{userProblemSetId}") + public ResponseEntity>> getProblemsByUserProblemSetId( + @PathVariable Long userProblemSetId + ) { + try { + List problems = userProblemService.getProblemsByUserProblemSetId(userProblemSetId); + + if (problems == null || problems.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(ApiResponse.failure(HttpStatus.NOT_FOUND, "해당 문제세트에 등록된 문제가 없습니다.")); + } + + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "문제 목록 조회 성공", problems)); + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "서버 오류로 문제 목록을 조회하지 못했습니다.")); + } + } + + // user_problem테이블에 문제들 일괄 등록 + @PostMapping("/sets/{userProblemSetId}") + public ResponseEntity> createUserProblems( + @PathVariable Long userProblemSetId, + @RequestBody List userProblems, + HttpSession session + ) { + Long memberId = (Long) session.getAttribute("member_id"); + if (memberId == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); + } + + try { + // 세트 ID 세팅 + for (UserProblem p : userProblems) { + p.setUserProblemSetId(userProblemSetId); + } + + int inserted = userProblemService.addUserProblems(userProblems); + + if (inserted == 0) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "문제 등록에 실패했습니다.")); + } + + return ResponseEntity.status(HttpStatus.CREATED) + .body(ApiResponse.success(HttpStatus.CREATED, "문제 등록 성공", null)); + + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "서버 오류로 문제를 등록하지 못했습니다.")); + } + } + + // 문제 수정 + @PutMapping("/{userProblemId}") + public ResponseEntity> updateUserProblem( + @PathVariable Long userProblemId, + @RequestBody UserProblem userProblem, + HttpSession session + ) { + Long memberId = (Long) session.getAttribute("member_id"); + if (memberId == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); + } + + try { + userProblem.setUserProblemId(userProblemId); + + int result = userProblemService.updateUserProblem(userProblem); + + if (result == 0) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(ApiResponse.failure(HttpStatus.NOT_FOUND, "수정할 문제가 존재하지 않습니다.")); + } + + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "문제 수정 성공", null)); + + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "서버 오류로 문제를 수정하지 못했습니다.")); + } + } + + // 문제 삭제 + @DeleteMapping("/{userProblemId}") + public ResponseEntity> deleteUserProblem( + @PathVariable Long userProblemId, + HttpSession session + ) { + Long memberId = (Long) session.getAttribute("member_id"); + if (memberId == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); + } + + try { + int result = userProblemService.deleteUserProblem(userProblemId); + + if (result == 0) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(ApiResponse.failure(HttpStatus.NOT_FOUND, "삭제할 문제가 존재하지 않습니다.")); + } + + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "문제 삭제 성공", null)); + + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "서버 오류로 문제를 삭제하지 못했습니다.")); + } + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java new file mode 100644 index 0000000..021943a --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java @@ -0,0 +1,135 @@ +package com.codeboy.mvc.controller; + +import com.codeboy.mvc.model.dto.UserProblemSet; +import com.codeboy.mvc.model.responseDto.ApiResponse; // 실제 패키지에 맞게 수정 +import com.codeboy.mvc.model.service.UserProblemSetService; +import jakarta.servlet.http.HttpSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/user-problem-sets") +public class UserProblemSetController { + + + private final UserProblemSetService userProblemSetService; + + public UserProblemSetController(UserProblemSetService userProblemSetService) { + this.userProblemSetService = userProblemSetService; + } + + // 모든 문제 세트 조회 + @GetMapping + public ResponseEntity>> getAllUserProblemSets() { + try { + List sets = userProblemSetService.getAllUserProblemSets(); + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "유저 문제세트 전체 조회 성공", sets)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "서버 오류로 문제세트를 조회하지 못했습니다.")); + } + } + + // 마이페이지 - 내가 만든 문제세트 조회 + @GetMapping("/me") + public ResponseEntity> getMyUserProblemSet(HttpSession session) { + Long memberId = (Long) session.getAttribute("member_id"); + if (memberId == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); + } + + try { + UserProblemSet set = userProblemSetService.getUserProblemSetByMemberId(memberId); + + if (set == null) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(ApiResponse.failure(HttpStatus.NOT_FOUND, "등록된 유저 문제세트가 없습니다.")); + } + + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "나의 유저 문제세트 조회 성공", set)); + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "서버 오류로 나의 문제세트를 조회하지 못했습니다.")); + } + } + + // 마이페이지 - 문제세트 생성 + @PostMapping + public ResponseEntity> createMyUserProblemSet(HttpSession session) { + Long memberId = (Long) session.getAttribute("member_id"); + if (memberId == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); + } + + try { + //문제 세트가 생성되기전에는 PK가 존재하질 않아서 + //문제세트를 등록함과 동시에 이 PK값을 UserProblemController에도 넘겨줘야함. + //따라서 UserProblemSet 객체를 생성하여 memberId를 세팅해서 넘겨줌, + //프론트에서 이를 받아서 다시 문제 하나하나를 user_problem테이블에 저장 할 때 이 userProblemSetId를 같이 넘겨줘야함. + //이 부분은 프론트와 백엔드간의 협의가 필요. + //UserProblemSetMapper에도 generateKey를 추가해서 PK값을 set에 담을 수 있었다. + UserProblemSet set = new UserProblemSet(); + set.setMemberId(memberId); + int result = userProblemSetService.createUserProblemSet(set); + + if (result == 0) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "유저 문제세트 생성에 실패했습니다.")); + } + + return ResponseEntity.status(HttpStatus.CREATED) + .body(ApiResponse.success(HttpStatus.CREATED, "유저 문제세트 생성 성공", null)); + + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "서버 오류로 문제세트를 생성하지 못했습니다.")); + } + } + + // 마이페이지 - 문제세트 삭제 + @DeleteMapping("/{userProblemSetId}") + public ResponseEntity> deleteUserProblemSet( + @PathVariable Long userProblemSetId, + HttpSession session + ) { + Long memberId = (Long) session.getAttribute("member_id"); + if (memberId == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); + } + + // TODO: userProblemSetId가 memberId가 만든 세트인지 owner 체크 로직을 Service/Dao에 추가하면 더 안전함 + + try { + int result = userProblemSetService.deleteUserProblemSet(userProblemSetId); + + if (result == 0) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(ApiResponse.failure(HttpStatus.NOT_FOUND, "삭제할 유저 문제세트가 존재하지 않습니다.")); + } + + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "유저 문제세트 삭제 성공", null)); + + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "서버 오류로 문제세트를 삭제하지 못했습니다.")); + } + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemDao.java index de918f4..61f7b11 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemDao.java @@ -17,7 +17,8 @@ public interface UserProblemDao extends ProblemDao{ int updateUserProblem(UserProblem userProblem); //제작자 본인이 자신의 문제를 삭제하는 로직 - int deleteUserProblem(Long userProblemId); + int deleteUserProblemById(Long userProblemId); + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java index f08f709..e2649b6 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java @@ -12,14 +12,14 @@ public interface UserProblemSetDao { //마이페이지에서 자신이 제작한 문제세트 조회 - List selectUserProblemSetByMemberId(Long memberId); + UserProblemSet selectUserProblemSetByMemberId(Long memberId); //문제 세트 등록 memberId = 문제 제작자만 넘겨주고 문제들은 problemDao에서 insertUserProblem으로 넣음 (마이페이지에서 생성) int insertUserProblemSet(Long memberId); // 문제세트 삭제 (마이페이지에서 삭제) - int deleteUserProblemSetById(long userProblemSetId); - + int deleteUserProblemSetById(Long userProblemSetId); + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblem.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblem.java index fa4f9b3..85aecc3 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblem.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblem.java @@ -14,7 +14,7 @@ @Getter @Setter public class UserProblem { - private long userProblemId; + private Long userProblemId; private String problemDescription; private Category category; private String choice1; @@ -23,5 +23,5 @@ public class UserProblem { private String choice4; private String answer; private int commentCount; - private long userProblemSetId; + private Long userProblemSetId; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblemSet.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblemSet.java index d460eb4..723d6af 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblemSet.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblemSet.java @@ -12,6 +12,6 @@ @Getter @Setter public class UserProblemSet { - private long userProblemSetId; - private long memberId; + private Long userProblemSetId; + private Long memberId; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemService.java index c315c3b..2a25a51 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemService.java @@ -1,5 +1,16 @@ package com.codeboy.mvc.model.service; -public class UserProblemService { +import com.codeboy.mvc.model.dto.UserProblem; +import java.util.List; + +public interface UserProblemService { + + List getProblemsByUserProblemSetId(Long userProblemSetId); + + int addUserProblems(List userProblems); + + int updateUserProblem(UserProblem userProblem); + + int deleteUserProblem(Long userProblemId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemServiceImpl.java new file mode 100644 index 0000000..d3c23a5 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemServiceImpl.java @@ -0,0 +1,46 @@ +package com.codeboy.mvc.model.service; + +import com.codeboy.mvc.model.dao.UserProblemDao; +import com.codeboy.mvc.model.dto.UserProblem; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class UserProblemServiceImpl implements UserProblemService { + + private final UserProblemDao userProblemDao; + + public UserProblemServiceImpl(UserProblemDao userProblemDao) { + this.userProblemDao = userProblemDao; + } + + @Override + public List getProblemsByUserProblemSetId(Long userProblemSetId) { + return userProblemDao.selectProblemsByUserProblemSetId(userProblemSetId); + } + + @Override + public int addUserProblems(List userProblems) { + if (userProblems == null || userProblems.isEmpty()) { + throw new IllegalArgumentException("등록할 문제가 하나 이상 있어야 합니다."); + } + return userProblemDao.insertUserProblemList(userProblems); + } + + @Override + public int updateUserProblem(UserProblem userProblem) { + if (userProblem == null || userProblem.getUserProblemId() == null) { + throw new IllegalArgumentException("수정할 문제를 찾을 수 없습니다. 문제Id를 확인하세요."); + } + return userProblemDao.updateUserProblem(userProblem); + } + + @Override + public int deleteUserProblem(Long userProblemId) { + if (userProblemId == null) { + throw new IllegalArgumentException("삭제할 문제를 찾을 수 없습니다. 삭제할 문제 ID를 확인하세요."); + } + return userProblemDao.deleteUserProblemById(userProblemId); + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetService.java new file mode 100644 index 0000000..e063488 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetService.java @@ -0,0 +1,15 @@ +package com.codeboy.mvc.model.service; + +import com.codeboy.mvc.model.dto.UserProblemSet; + +import java.util.List; + +public interface UserProblemSetService { + List getAllUserProblemSets(); + + UserProblemSet getUserProblemSetByMemberId(Long memberId); + + int createUserProblemSet(UserProblemSet set); + + int deleteUserProblemSet(Long userProblemSetId); +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetServiceImpl.java new file mode 100644 index 0000000..3d10892 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetServiceImpl.java @@ -0,0 +1,44 @@ +package com.codeboy.mvc.model.service; + +import com.codeboy.mvc.model.dao.UserProblemSetDao; +import com.codeboy.mvc.model.dto.UserProblemSet; +import org.springframework.stereotype.Service; + + +import java.util.List; + +@Service +public class UserProblemSetServiceImpl implements UserProblemSetService { + + private final UserProblemSetDao userProblemSetDao; + + public UserProblemSetServiceImpl(UserProblemSetDao userProblemSetDao) { + this.userProblemSetDao = userProblemSetDao; + } + + @Override + public List getAllUserProblemSets() { + return userProblemSetDao.selectUserProblemSets(); + } + + @Override + public UserProblemSet getUserProblemSetByMemberId(Long memberId) { + return userProblemSetDao.selectUserProblemSetByMemberId(memberId); + } + + @Override + public int createUserProblemSet(UserProblemSet set) { + if (set.getMemberId() == null) { + throw new IllegalArgumentException("회원 ID가 필요합니다."); + } + return userProblemSetDao.insertUserProblemSet(set.getMemberId()); + } + + @Override + public int deleteUserProblemSet(Long userProblemSetId) { + if (userProblemSetId == null) { + throw new IllegalArgumentException("삭제할 문제세트 ID가 필요합니다."); + } + return userProblemSetDao.deleteUserProblemSetById(userProblemSetId); + } +} diff --git a/codeBoy_backend/src/main/resources/mappers/UserProblemMapper.xml b/codeBoy_backend/src/main/resources/mappers/UserProblemMapper.xml index 8d1ff96..3168486 100644 --- a/codeBoy_backend/src/main/resources/mappers/UserProblemMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/UserProblemMapper.xml @@ -34,7 +34,7 @@ choice_3 = #{choice3}, choice_4 = #{choice4}, answer = #{answer}, - comment_count = #{commentCount}, + comment_count = #{commentCount} WHERE user_problem_id = #{userProblemId} diff --git a/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml b/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml index fb94fc7..3498e1b 100644 --- a/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml @@ -5,7 +5,7 @@ - SELECT * FROM user_problem_set @@ -18,7 +18,10 @@ - + INSERT INTO user_problem_set (member_id) VALUES (#{memberId}) @@ -26,7 +29,7 @@ DELETE FROM user_problem_set - WHERE id = #{id} + WHERE user_problem_set_id = #{userProblemSetId} From 920dab3fcca7b2298b0600c45dabf30f4abec0ed Mon Sep 17 00:00:00 2001 From: mingeung Date: Fri, 28 Nov 2025 10:18:00 +0900 Subject: [PATCH 25/61] =?UTF-8?q?refactor=20:=20response,=20request=20dto?= =?UTF-8?q?=20=ED=8F=B4=EB=8D=94=EB=A5=BC=20dto=20=ED=8F=B4=EB=8D=94=20?= =?UTF-8?q?=EC=95=88=EC=9C=BC=EB=A1=9C=20=EC=98=AE=EA=B8=B0=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../codeboy/mvc/controller/IncorrectNoteController.java | 6 +++--- .../com/codeboy/mvc/controller/ProblemController.java | 2 +- .../com/codeboy/mvc/controller/QuizRoomController.java | 8 +++----- .../java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java | 2 +- .../main/java/com/codeboy/mvc/model/dao/MemberDao.java | 2 +- .../main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java | 2 +- .../{requestDto => dto/request}/IncorrectNoteRequest.java | 2 +- .../{requestDto => dto/request}/JoinQuizRoomRequest.java | 2 +- .../{requestDto => dto/request}/MemberUpdateRequest.java | 2 +- .../model/{responseDto => dto/response}/ApiResponse.java | 2 +- .../response}/IncorrectNoteResponse.java | 2 +- .../response}/getQuizRoomMembersResponse.java | 2 +- .../codeboy/mvc/model/service/IncorrectNoteService.java | 2 +- .../java/com/codeboy/mvc/model/service/MemberService.java | 2 +- .../com/codeboy/mvc/model/service/QuizRoomService.java | 2 +- .../src/main/resources/mappers/QuizRoomMapper.xml | 2 +- .../classes/META-INF/maven/Backend/Backend/pom.properties | 2 +- 17 files changed, 21 insertions(+), 23 deletions(-) rename codeBoy_backend/src/main/java/com/codeboy/mvc/model/{requestDto => dto/request}/IncorrectNoteRequest.java (83%) rename codeBoy_backend/src/main/java/com/codeboy/mvc/model/{requestDto => dto/request}/JoinQuizRoomRequest.java (80%) rename codeBoy_backend/src/main/java/com/codeboy/mvc/model/{requestDto => dto/request}/MemberUpdateRequest.java (89%) rename codeBoy_backend/src/main/java/com/codeboy/mvc/model/{responseDto => dto/response}/ApiResponse.java (94%) rename codeBoy_backend/src/main/java/com/codeboy/mvc/model/{responseDto => dto/response}/IncorrectNoteResponse.java (90%) rename codeBoy_backend/src/main/java/com/codeboy/mvc/model/{responseDto => dto/response}/getQuizRoomMembersResponse.java (80%) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java index fd778bf..af4ecbb 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java @@ -1,8 +1,8 @@ package com.codeboy.mvc.controller; -import com.codeboy.mvc.model.requestDto.IncorrectNoteRequest; -import com.codeboy.mvc.model.responseDto.ApiResponse; -import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; +import com.codeboy.mvc.model.dto.request.IncorrectNoteRequest; +import com.codeboy.mvc.model.dto.response.ApiResponse; +import com.codeboy.mvc.model.dto.response.IncorrectNoteResponse; import com.codeboy.mvc.model.service.IncorrectNoteService; import org.apache.ibatis.javassist.NotFoundException; import org.springframework.http.HttpStatus; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java index cdc9698..96ad980 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java @@ -1,7 +1,7 @@ package com.codeboy.mvc.controller; import com.codeboy.common.Category; -import com.codeboy.mvc.model.responseDto.ApiResponse; +import com.codeboy.mvc.model.dto.response.ApiResponse; import com.codeboy.mvc.model.dto.Problem; import com.codeboy.mvc.model.service.ProblemServiceImpl; import org.springframework.beans.factory.annotation.Autowired; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java index 4a3c7aa..8335537 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java @@ -1,9 +1,9 @@ package com.codeboy.mvc.controller; import com.codeboy.mvc.model.dto.*; -import com.codeboy.mvc.model.requestDto.JoinQuizRoomRequest; -import com.codeboy.mvc.model.responseDto.ApiResponse; -import com.codeboy.mvc.model.responseDto.getQuizRoomMembersResponse; +import com.codeboy.mvc.model.dto.request.JoinQuizRoomRequest; +import com.codeboy.mvc.model.dto.response.ApiResponse; +import com.codeboy.mvc.model.dto.response.getQuizRoomMembersResponse; import com.codeboy.mvc.model.service.QuizRoomService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -85,9 +85,7 @@ public ResponseEntity>> getQuizRoomList() { public ResponseEntity>> getQuizRoomMembers(@PathVariable long roomId) { try { List memberList = quizRoomService.getOneQuizRoomMember(roomId); - return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "멤버 리스트를 반환합니다.", memberList)); - } catch (IllegalStateException | IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java index 33b999b..2782bb9 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/IncorrectNoteDao.java @@ -3,7 +3,7 @@ import java.util.List; import java.util.Map; -import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; +import com.codeboy.mvc.model.dto.response.IncorrectNoteResponse; import org.apache.ibatis.annotations.Mapper; @Mapper diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java index 8b7c729..f91da1f 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java @@ -1,7 +1,7 @@ package com.codeboy.mvc.model.dao; import com.codeboy.mvc.model.dto.Member; -import com.codeboy.mvc.model.requestDto.MemberUpdateRequest; +import com.codeboy.mvc.model.dto.request.MemberUpdateRequest; public interface MemberDao { public void insertMember(Member member); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java index 7ba8f08..f831191 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java @@ -4,7 +4,7 @@ import com.codeboy.mvc.model.dto.QuizRoom; import com.codeboy.mvc.model.dto.QuizRoomMember; -import com.codeboy.mvc.model.responseDto.getQuizRoomMembersResponse; +import com.codeboy.mvc.model.dto.response.getQuizRoomMembersResponse; import org.apache.ibatis.annotations.Mapper; @Mapper diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/IncorrectNoteRequest.java similarity index 83% rename from codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java rename to codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/IncorrectNoteRequest.java index 2ab3592..ffc92f4 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/IncorrectNoteRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/IncorrectNoteRequest.java @@ -1,4 +1,4 @@ -package com.codeboy.mvc.model.requestDto; +package com.codeboy.mvc.model.dto.request; import lombok.*; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/JoinQuizRoomRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/JoinQuizRoomRequest.java similarity index 80% rename from codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/JoinQuizRoomRequest.java rename to codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/JoinQuizRoomRequest.java index ba0602a..079bd8c 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/JoinQuizRoomRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/JoinQuizRoomRequest.java @@ -1,4 +1,4 @@ -package com.codeboy.mvc.model.requestDto; +package com.codeboy.mvc.model.dto.request; import lombok.*; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/MemberUpdateRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/MemberUpdateRequest.java similarity index 89% rename from codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/MemberUpdateRequest.java rename to codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/MemberUpdateRequest.java index d742835..ba6935d 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/requestDto/MemberUpdateRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/MemberUpdateRequest.java @@ -1,4 +1,4 @@ -package com.codeboy.mvc.model.requestDto; +package com.codeboy.mvc.model.dto.request; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/ApiResponse.java similarity index 94% rename from codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java rename to codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/ApiResponse.java index 5960232..5617ce4 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/ApiResponse.java @@ -1,4 +1,4 @@ -package com.codeboy.mvc.model.responseDto; +package com.codeboy.mvc.model.dto.response; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/IncorrectNoteResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/IncorrectNoteResponse.java similarity index 90% rename from codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/IncorrectNoteResponse.java rename to codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/IncorrectNoteResponse.java index 58cafcd..f86a4c2 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/IncorrectNoteResponse.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/IncorrectNoteResponse.java @@ -1,4 +1,4 @@ -package com.codeboy.mvc.model.responseDto; +package com.codeboy.mvc.model.dto.response; import com.codeboy.common.Category; import lombok.*; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/getQuizRoomMembersResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/getQuizRoomMembersResponse.java similarity index 80% rename from codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/getQuizRoomMembersResponse.java rename to codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/getQuizRoomMembersResponse.java index 7825274..3128f08 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/getQuizRoomMembersResponse.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/getQuizRoomMembersResponse.java @@ -1,4 +1,4 @@ -package com.codeboy.mvc.model.responseDto; +package com.codeboy.mvc.model.dto.response; import lombok.*; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java index 460a9fa..a3a64b2 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/IncorrectNoteService.java @@ -1,7 +1,7 @@ package com.codeboy.mvc.model.service; import com.codeboy.mvc.model.dao.IncorrectNoteDao; -import com.codeboy.mvc.model.responseDto.IncorrectNoteResponse; +import com.codeboy.mvc.model.dto.response.IncorrectNoteResponse; import org.apache.ibatis.javassist.NotFoundException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java index 3fa2195..1e6d6b5 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java @@ -1,7 +1,7 @@ package com.codeboy.mvc.model.service; import com.codeboy.mvc.model.dto.Member; -import com.codeboy.mvc.model.requestDto.MemberUpdateRequest; +import com.codeboy.mvc.model.dto.request.MemberUpdateRequest; public interface MemberService { //회원가입 diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java index 02cedaa..7e2ed77 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java @@ -2,7 +2,7 @@ import java.util.List; -import com.codeboy.mvc.model.responseDto.getQuizRoomMembersResponse; +import com.codeboy.mvc.model.dto.response.getQuizRoomMembersResponse; import org.springframework.beans.factory.annotation.Autowired; import com.codeboy.mvc.model.dao.QuizRoomDao; diff --git a/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml b/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml index 0a75a1e..5a98f52 100644 --- a/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml @@ -32,7 +32,7 @@ - + - SELECT - qrm.member_id, + qrm.member_id AS memberId, m.nickname FROM quiz_room_member qrm JOIN member m ON qrm.member_id = m.member_id From 5bd570a7c620bc14686f1b61cf001079b4fe17e0 Mon Sep 17 00:00:00 2001 From: mingeung Date: Fri, 28 Nov 2025 14:01:57 +0900 Subject: [PATCH 28/61] =?UTF-8?q?feat=20:=20=ED=9A=8C=EC=9B=90=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C,=20=EC=88=98=EC=A0=95,=20=EC=82=AD=EC=A0=9C=20API=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/codeboy/common/Status.java | 6 - .../mvc/controller/MemberController.java | 114 +++++++++++++++--- .../com/codeboy/mvc/model/dao/MemberDao.java | 21 +++- .../com/codeboy/mvc/model/dto/Member.java | 4 +- .../dto/request/DuplicateCheckRequest.java | 14 +++ .../dto/request/MemberUpdateRequest.java | 2 +- .../dto/response/DuplicateCheckResponse.java | 15 +++ .../mvc/model/service/MemberService.java | 95 +++++++++++++-- .../mvc/model/service/QuizRoomService.java | 1 - .../main/resources/mappers/MemberMapper.xml | 58 +++++++++ .../src/main/resources/mappers/UserMapper.xml | 8 -- 11 files changed, 291 insertions(+), 47 deletions(-) delete mode 100644 codeBoy_backend/src/main/java/com/codeboy/common/Status.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/DuplicateCheckRequest.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/DuplicateCheckResponse.java create mode 100644 codeBoy_backend/src/main/resources/mappers/MemberMapper.xml delete mode 100644 codeBoy_backend/src/main/resources/mappers/UserMapper.xml diff --git a/codeBoy_backend/src/main/java/com/codeboy/common/Status.java b/codeBoy_backend/src/main/java/com/codeboy/common/Status.java deleted file mode 100644 index b3ad7e4..0000000 --- a/codeBoy_backend/src/main/java/com/codeboy/common/Status.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.codeboy.common; - -public enum Status { - ACTIVE, - INACTIVE -} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java index 132b18a..d890b56 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java @@ -1,32 +1,114 @@ package com.codeboy.mvc.controller; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import com.codeboy.mvc.model.dto.request.DuplicateCheckRequest; +import com.codeboy.mvc.model.dto.request.MemberUpdateRequest; +import com.codeboy.mvc.model.dto.response.ApiResponse; +import com.codeboy.mvc.model.dto.response.DuplicateCheckResponse; +import com.codeboy.mvc.model.service.IncorrectNoteService; +import com.codeboy.mvc.model.service.MemberService; +import org.apache.coyote.Response; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; import com.codeboy.mvc.model.dto.Member; import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.NoSuchElementException; + @RestController -@RequestMapping("/api-member") -@Tag(name="Member RESTful API", description = "Member CRUD를 할 수 있는 REST API") +@RequestMapping("/api/member") +@Tag(name = "Member RESTful API", description = "Member CRUD를 할 수 있는 REST API") public class MemberController { -// @Autowired -// private MemberService memberService; + private final MemberService memberService; + + public MemberController(MemberService memberService) { + this.memberService = memberService; + } + + //회원 조회 + @GetMapping + //TODO: memberID 넣기 + public ResponseEntity> getMemberInfo() { + Long memberId = 1L; + try { + Member member = memberService.getMemberById(memberId); + return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "회원정보가 조회되었습니다", member)); + + } catch (NoSuchElementException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.failure(HttpStatus.NOT_FOUND, e.getMessage())); + + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } + } + + //회원 탈퇴 + @DeleteMapping() + public ResponseEntity> deleteMember() { + //TODO : memberId 받아오기 + Long memberId = 1L; + try { + memberService.deactivateMember(memberId); + return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "회원이 성공적으로 삭제되었습니다.")); + + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } catch (NoSuchElementException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.failure(HttpStatus.NOT_FOUND, e.getMessage())); + } + } + + //회원 정보 업데이트 + @PatchMapping + public ResponseEntity> updateMember(@RequestBody MemberUpdateRequest request) { + //TODO : memberId 받아오기 + Long memberId = 1L; + try { + memberService.updateMember(memberId, request); + return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "회원정보 업데이트에 성공했습니다.")); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } catch (IllegalStateException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponse.failure(HttpStatus.NOT_FOUND, e.getMessage())); + } + } + //ID, 닉네임, 이메일 중복체크 + @PostMapping("/check-id") + public ResponseEntity> checkId(@RequestBody DuplicateCheckRequest request) { + try { + boolean duplicated = memberService.checkIdDuplicate(request.getValue()); + DuplicateCheckResponse response = new DuplicateCheckResponse(duplicated); + return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "아이디 중복 확인 완료", response)); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } + } -// @PostMapping("/signup") -// public String signup(@ModelAttribute Member member){ -// return "회원가입 성공?"; -// } -// -// @GetMapping(){ -// -// } + @PostMapping("/check-email") + public ResponseEntity> checkEmail(@RequestBody DuplicateCheckRequest request) { + try { + boolean duplicated = memberService.checkEmailDuplicate(request.getValue()); + DuplicateCheckResponse response = new DuplicateCheckResponse(duplicated); + return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "이메일 중복 확인 완료", response)); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } + } + @PostMapping("/check-nickname") + public ResponseEntity> checkNickname(@RequestBody DuplicateCheckRequest request) { + try { + boolean duplicated = memberService.checkNicknameDuplicate(request.getValue()); + DuplicateCheckResponse response = new DuplicateCheckResponse(duplicated); + return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "닉네임 중복 확인 완료", response)); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } + } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java index f91da1f..0a4dcd1 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java @@ -2,17 +2,30 @@ import com.codeboy.mvc.model.dto.Member; import com.codeboy.mvc.model.dto.request.MemberUpdateRequest; - +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +@Mapper public interface MemberDao { public void insertMember(Member member); - public Member selectMember(String id, String password); + public Member selectMemberById(Long memberId); //멤버 삭제 -> db에서는 status 변경 - public void delete(int memberId); + public int deactivateMemberById(Long memberId); //멤버 업데이트 -> db에서는 patch(nickname, email, id) - public void updateMember(long memberId, MemberUpdateRequest memberUpdateRequest); + public int updateMemberById(@Param("memberId") Long memberId, @Param("update") MemberUpdateRequest memberUpdateRequest); + + //아이디 중복 체크 + boolean existsId(String id); + + //닉네임 중복 체크 + boolean existsNickname(String nickname); + + //이메일 중복 체크 + boolean existsEmail(String email); + //멤버가 활성화 상태인지 확인 + boolean isMemberActive(Long memberId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java index a3c174a..b5209bc 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java @@ -2,8 +2,6 @@ import java.sql.Timestamp; -import com.codeboy.common.Status; - import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Getter; @@ -22,7 +20,7 @@ public class Member { private String nickname; private String email; private Timestamp signupDate; - private Status status; + private Boolean isActive; private Timestamp deletedDate; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/DuplicateCheckRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/DuplicateCheckRequest.java new file mode 100644 index 0000000..8a366f4 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/DuplicateCheckRequest.java @@ -0,0 +1,14 @@ +package com.codeboy.mvc.model.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class DuplicateCheckRequest { + private String value; +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/MemberUpdateRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/MemberUpdateRequest.java index ba6935d..9724291 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/MemberUpdateRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/MemberUpdateRequest.java @@ -12,7 +12,7 @@ @Setter @Schema(description="유저 정보 수정 DTO") public class MemberUpdateRequest { - private String nickName; + private String nickname; private String id; private String email; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/DuplicateCheckResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/DuplicateCheckResponse.java new file mode 100644 index 0000000..17a6543 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/DuplicateCheckResponse.java @@ -0,0 +1,15 @@ +package com.codeboy.mvc.model.dto.response; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Setter +public class DuplicateCheckResponse { + private boolean duplicated; +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java index 1e6d6b5..9fe9606 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java @@ -1,18 +1,97 @@ package com.codeboy.mvc.model.service; +import com.codeboy.mvc.model.dao.MemberDao; import com.codeboy.mvc.model.dto.Member; import com.codeboy.mvc.model.dto.request.MemberUpdateRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; -public interface MemberService { - //회원가입 - public void signupMember(); +import java.util.NoSuchElementException; + +@Service +public class MemberService { + @Autowired + MemberDao memberDao; //회원 정보 가져오기기 - public Member readMember(String id, String password); + public Member getMemberById(Long memberId) { + isMemberExist(memberId); + + Member member = memberDao.selectMemberById(memberId); + if (member == null) { + throw new NoSuchElementException("Id에 해당하는 회원 정보를 찾을 수 없습니다. memberId:" + memberId); + } + return member; + }; //회원 탈퇴 - public void withdrawal(int memberId); + public void deactivateMember(Long memberId){ + isMemberExist(memberId); + + int updatedRows = memberDao.deactivateMemberById(memberId); + if (updatedRows == 0) { + throw new IllegalStateException("회원 탈퇴 실패 : memberId: " + memberId); + } + } + + + public void updateMember(Long memberId, MemberUpdateRequest memberUpdateRequest){ + isMemberExist(memberId); + //중복된 id, email이 있는지 검증 로직 + String id = memberUpdateRequest.getId(); + String nickname = memberUpdateRequest.getNickname(); + String email = memberUpdateRequest.getEmail(); + validateMemberUpdate(id, nickname, email); + + int affectedRows = memberDao.updateMemberById(memberId, memberUpdateRequest); + + if (affectedRows == 0) { + throw new IllegalStateException("회원 정보 수정에 실패하였습니다. memberId: " + memberId); + } + + }; + public boolean checkIdDuplicate(String id) { + if (id == null) { + throw new IllegalArgumentException("유효하지 않은 Id 입니다."); + } + return memberDao.existsId(id); + } + + public boolean checkNicknameDuplicate(String nickname ) { + if (nickname == null) { + throw new IllegalArgumentException("유효하지 않은 Id 입니다."); + } + return memberDao.existsNickname(nickname); + } + + public boolean checkEmailDuplicate(String email) { + if (email == null) { + throw new IllegalArgumentException("유효하지 않은 Id 입니다."); + } + return memberDao.existsEmail(email); + } + public void isMemberExist(Long memberId) { + if (memberId == null) { + throw new IllegalArgumentException("유효하지 않은 memberId입니다. memberId: " ); + } + + boolean isActive = memberDao.isMemberActive(memberId); + if (!isActive) { + throw new IllegalArgumentException("비활성화된 멤버 id 입니다. memberId: " + memberId); + } + } + + // 최종 제출 시 전체 검증 + public void validateMemberUpdate(String id, String nickname, String email) { + if (memberDao.existsId(id)) { + throw new IllegalArgumentException("중복된 ID입니다."); + } + if (memberDao.existsNickname(nickname)) { + throw new IllegalArgumentException("중복된 닉네임입니다."); + } + if (memberDao.existsEmail(email)) { + throw new IllegalArgumentException("중복된 이메일입니다."); + } + } - //회원정보 수정-> db에서는 patch(nickname, email, id) - public void updateMember(long memberId, MemberUpdateRequest memberUpdateRequest); -} +}; \ No newline at end of file diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java index 07fd19a..ea246e0 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java @@ -27,7 +27,6 @@ public List getOneQuizRoomMember(long roomId) { validateRoomId(roomId); List memberList = quizRoomDao.selectOneQuizRoom(roomId); - System.out.println("멤버리스트: " + memberList); if (memberList.isEmpty()) { throw new IllegalStateException("퀴즈방에 참가자가 없습니다."); } diff --git a/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml new file mode 100644 index 0000000..e5f3596 --- /dev/null +++ b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml @@ -0,0 +1,58 @@ + + + + + + + UPDATE member + SET is_active = 0 + WHERE member_id = #{memberId} + + + + UPDATE member + + + nickname = #{update.nickname} + + + id = #{update.id} + + + email = #{update.email} + + + WHERE member_id = #{memberId} + + + + + + + + + + \ No newline at end of file diff --git a/codeBoy_backend/src/main/resources/mappers/UserMapper.xml b/codeBoy_backend/src/main/resources/mappers/UserMapper.xml deleted file mode 100644 index 39d9eb4..0000000 --- a/codeBoy_backend/src/main/resources/mappers/UserMapper.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file From 4219aa191738fba59df7570de77a594dc1db2114 Mon Sep 17 00:00:00 2001 From: mingeung Date: Fri, 28 Nov 2025 14:09:45 +0900 Subject: [PATCH 29/61] =?UTF-8?q?refactor=20:=20problem=EC=9D=98=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20service=EC=97=90=EC=84=9C=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mvc/controller/MemberController.java | 4 +--- .../mvc/controller/ProblemController.java | 18 ++++-------------- .../com/codeboy/mvc/model/dao/MemberDao.java | 8 ++++---- .../mvc/model/service/ProblemServiceImpl.java | 15 ++++++++++++++- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java index d890b56..e1e736c 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java @@ -46,7 +46,7 @@ public ResponseEntity> getMemberInfo() { } //회원 탈퇴 - @DeleteMapping() + @DeleteMapping public ResponseEntity> deleteMember() { //TODO : memberId 받아오기 Long memberId = 1L; @@ -109,6 +109,4 @@ public ResponseEntity> checkNickname(@Reques return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); } } - - } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java index 96ad980..c0ecf1c 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java @@ -20,22 +20,12 @@ public class ProblemController { @GetMapping public ResponseEntity>> getProblems(@RequestParam int limit, @RequestParam Category category) { - if (limit <= 0) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "유효하지 않은 limit 입니다", null - )); - } - if (category == null) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "유효하지 않은 category 입니다.",null - )); - } - + try { List problems = problemService.getProblems(limit, category); + return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(HttpStatus.OK, "문제가 성공적으로 반환되었습니다.", problems)); - //만약 요청 수보다 존재하는 문제 수가 적다면 - if (limit > problems.size()) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, "요청보다 존재하는 문제 수가 적습니다.", null)); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse<>(HttpStatus.BAD_REQUEST, e.getMessage(), null)); } - - return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(HttpStatus.OK, "문제가 성공적으로 반환되었습니다.", problems)); } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java index 0a4dcd1..1315342 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java @@ -6,15 +6,15 @@ import org.apache.ibatis.annotations.Param; @Mapper public interface MemberDao { - public void insertMember(Member member); + void insertMember(Member member); - public Member selectMemberById(Long memberId); + Member selectMemberById(Long memberId); //멤버 삭제 -> db에서는 status 변경 - public int deactivateMemberById(Long memberId); + int deactivateMemberById(Long memberId); //멤버 업데이트 -> db에서는 patch(nickname, email, id) - public int updateMemberById(@Param("memberId") Long memberId, @Param("update") MemberUpdateRequest memberUpdateRequest); + int updateMemberById(@Param("memberId") Long memberId, @Param("update") MemberUpdateRequest memberUpdateRequest); //아이디 중복 체크 boolean existsId(String id); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java index 1750269..710c837 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java @@ -15,6 +15,19 @@ public class ProblemServiceImpl implements ProblemService{ @Override public List getProblems(int limit, Category category) { - return problemDao.selectProblem(limit,category); + if (limit <= 0) { + throw new IllegalArgumentException("limit의 수는 0이상이어야 합니다. limit: " + limit); + } + if (category == null) { + throw new IllegalArgumentException("category의 값은 null이 될 수 없습니다. : category: "); + } + List problems = problemDao.selectProblem(limit,category); + + //만약 요청 수보다 존재하는 문제 수가 적다면 + if (limit > problems.size()) { + throw new IllegalArgumentException("limit의 값은 문제 수보다 클 수 없습니다. problems: " + problems.size()); + } + + return problems; } } From 1b88d4b71a7c61d77e628588e4be93dfa36f4ddb Mon Sep 17 00:00:00 2001 From: junhyung8795 Date: Sun, 30 Nov 2025 14:22:16 +0900 Subject: [PATCH 30/61] =?UTF-8?q?api=ED=85=8C=EC=8A=A4=ED=8A=B8=2092?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=86=B5=EA=B3=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/codeboy/common/Status.java | 6 + .../mvc/controller/CommentController.java | 18 ++- .../controller/IncorrectNoteController.java | 11 +- .../mvc/controller/MemberController.java | 85 ++++++++---- .../mvc/controller/ProblemController.java | 1 + .../mvc/controller/UserProblemController.java | 8 +- .../controller/UserProblemSetController.java | 11 +- .../com/codeboy/mvc/model/dao/MemberDao.java | 14 +- .../mvc/model/dao/UserProblemSetDao.java | 2 +- .../codeboy/mvc/model/dto/IncorrectNote.java | 1 + .../com/codeboy/mvc/model/dto/Member.java | 55 +------- .../codeboy/mvc/model/dto/UserProblemSet.java | 2 + .../mvc/model/dto/request/LoginRequest.java | 2 +- .../mvc/model/dto/response/ApiResponse.java | 13 +- .../mvc/model/responseDto/ApiResponse.java | 30 ----- .../mvc/model/service/MemberService.java | 104 +++------------ .../mvc/model/service/MemberServiceImpl.java | 122 ++++++++++++++---- .../mvc/model/service/ProblemServiceImpl.java | 1 + .../service/UserProblemSetServiceImpl.java | 6 +- .../main/resources/mappers/CommentMapper.xml | 21 +-- .../main/resources/mappers/MemberMapper.xml | 14 +- 21 files changed, 275 insertions(+), 252 deletions(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/common/Status.java delete mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java diff --git a/codeBoy_backend/src/main/java/com/codeboy/common/Status.java b/codeBoy_backend/src/main/java/com/codeboy/common/Status.java new file mode 100644 index 0000000..b3ad7e4 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/common/Status.java @@ -0,0 +1,6 @@ +package com.codeboy.common; + +public enum Status { + ACTIVE, + INACTIVE +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java index 2da87f0..115df0d 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java @@ -3,8 +3,8 @@ import java.util.ArrayList; import java.util.List; -import com.codeboy.mvc.model.requestDto.CommentUpdateRequest; -import com.codeboy.mvc.model.responseDto.ApiResponse; +import com.codeboy.mvc.model.dto.request.CommentUpdateRequest; +import com.codeboy.mvc.model.dto.response.ApiResponse; import jakarta.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -50,12 +50,18 @@ public ResponseEntity>> getAllCommentsById(@PathVariab @PostMapping("{userProblemSetId}") public ResponseEntity> addComment(@PathVariable long userProblemSetId, - @RequestBody Comment comment) { + @RequestBody Comment comment, HttpSession session) { if (comment.getContent() == null || comment.getContent().isBlank()) { return ResponseEntity.status(HttpStatus.BAD_REQUEST) .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "댓글 내용은 비어 있을 수 없습니다.")); } - + Long memberId = (Long) session.getAttribute("memberId"); + if (memberId == null) { + // 인증 안 됨 + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); + } + comment.setMemberId(memberId); int result = commentService.addComment(userProblemSetId, comment); if (result == 0) { @@ -76,7 +82,7 @@ public ResponseEntity> updateComment( @RequestBody CommentUpdateRequest commentUpdateRequest, HttpSession session) { - Long memberId = (Long) session.getAttribute("member_id"); + Long memberId = (Long) session.getAttribute("memberId"); if (memberId == null) { // 인증 안 됨 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) @@ -117,7 +123,7 @@ public ResponseEntity> deleteComment(@PathVariable long userPr @PathVariable long commentId, HttpSession session) { - Long memberId = (Long) session.getAttribute("member_id"); + Long memberId = (Long) session.getAttribute("memberId"); // 로그인 안한 상태 if (memberId == null) { diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java index af4ecbb..be39c2d 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java @@ -4,6 +4,9 @@ import com.codeboy.mvc.model.dto.response.ApiResponse; import com.codeboy.mvc.model.dto.response.IncorrectNoteResponse; import com.codeboy.mvc.model.service.IncorrectNoteService; + +import jakarta.servlet.http.HttpSession; + import org.apache.ibatis.javassist.NotFoundException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -23,10 +26,10 @@ public IncorrectNoteController(IncorrectNoteService incorrectNoteService) { //한 회원의 오답노트를 모두 조회 @GetMapping - public ResponseEntity>> getIncorrectNote() { + public ResponseEntity>> getIncorrectNote(HttpSession session) { try { //TODO : 세션 or spring security에서 memberId 가져오기 - Long memberId = 1L; + Long memberId = (Long) session.getAttribute("memberId"); List incorrectNoteList = incorrectNoteService.getIncorrectNoteList(memberId); return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "오답노트가 성공적으로 조회되었습니다", incorrectNoteList)); } catch (IllegalArgumentException e) { @@ -38,9 +41,9 @@ public ResponseEntity>> getIncorrectNote //오답노트에 문제 넣기 @PostMapping - public ResponseEntity> addIncorrectNote(@RequestBody IncorrectNoteRequest incorrectNoteRequest) { + public ResponseEntity> addIncorrectNote(@RequestBody IncorrectNoteRequest incorrectNoteRequest, HttpSession session) { //TODO : 세션에서 멤버 id 가져오기 - Long memberId = 1L; + Long memberId = (Long) session.getAttribute("memberId"); Long problemId = incorrectNoteRequest.getProblemId(); Long userProblemId = incorrectNoteRequest.getUserProblemId(); Boolean isUserProblem = incorrectNoteRequest.getIsUserProblem(); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java index 04ed442..8e46fa6 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java @@ -1,29 +1,28 @@ package com.codeboy.mvc.controller; -import com.codeboy.mvc.model.requestDto.MemberUpdateRequest; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatusCode; - +import com.codeboy.mvc.model.dto.Member; import com.codeboy.mvc.model.dto.request.DuplicateCheckRequest; +import com.codeboy.mvc.model.dto.request.LoginRequest; import com.codeboy.mvc.model.dto.request.MemberUpdateRequest; import com.codeboy.mvc.model.dto.response.ApiResponse; import com.codeboy.mvc.model.dto.response.DuplicateCheckResponse; -import com.codeboy.mvc.model.service.IncorrectNoteService; -import com.codeboy.mvc.model.service.MemberService; -import org.apache.coyote.Response; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpSession; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatusCode; + import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import com.codeboy.mvc.model.dto.Member; -import com.codeboy.mvc.model.requestDto.LoginRequest; import com.codeboy.mvc.model.service.MemberService; -import java.net.URI; +import java.net.URI; +import java.util.HashMap; import java.util.NoSuchElementException; @RestController @@ -76,10 +75,37 @@ public ResponseEntity signUp(@RequestBody Member member) { * 401 실패 시 { error: "로그인 실패" } */ @PostMapping("/auth/login") - public ResponseEntity login(@RequestBody LoginRequest request) { - return null; + public ResponseEntity> login(@RequestBody LoginRequest request, HttpSession session) { + try { + // Service를 통해 로그인 처리 + Member member = memberService.login(request.getId(), request.getPassword()); + + // 세션에 member_id 저장 + session.setAttribute("memberId", member.getMemberId()); + session.setAttribute("id", member.getId()); + session.setAttribute("nickname", member.getNickname()); + + // 성공 응답 반환 + + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "로그인 성공", + new HashMap() {private static final long serialVersionUID = 5698154608853982208L; + + { + put("memberId", member.getMemberId()); + put("nickname", member.getNickname()); + put("id", member.getId()); + }})); + } catch (IllegalArgumentException e) { + // 로그인 실패 (ID/비밀번호 오류 등) + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, e.getMessage())); + } catch (Exception e) { + // 기타 오류 + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "로그인 처리 중 오류가 발생했습니다.")); + } } - /** * 로그아웃 * POST /api/auth/logout @@ -88,10 +114,14 @@ public ResponseEntity login(@RequestBody LoginRequest request) { * 204 성공 시 본문 없음 */ @PostMapping("/auth/logout") - public ResponseEntity logout() { - return null; + public ResponseEntity> logout(HttpSession session) { + // 세션 무효화 + session.invalidate(); + + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "로그아웃 성공", null)); + } - /** * 내 정보 수정 * PUT /api/members/me @@ -106,7 +136,7 @@ public ResponseEntity logout() { public ResponseEntity updateMe(@RequestBody MemberUpdateRequest request, @PathVariable long memberId ) { //파라미터로 memberId받아서 해당회원의 정보를 수정 - Member member = memberService.getMemberByMemberId(memberId); + Member member = memberService.getMemberById(memberId); //회원을 못찾는 경우 ->존재하지 않는 memberId인경우 if (member == null) { return ResponseEntity @@ -115,18 +145,27 @@ public ResponseEntity updateMe(@RequestBody MemberUpdateRequest request, @Pat } //닉네임과 이메일은 바꿀 수 있다고 가정. 필요하면 ID도..? - if (request.getNickName() != null) { - member.setNickname(request.getNickName()); + if (request.getNickname() != null) { + member.setNickname(request.getNickname()); + return ResponseEntity + .status(HttpStatusCode.valueOf(401)) + .body("닉네임이 없습니다.."); } if (request.getEmail() != null) { member.setEmail(request.getEmail()); + return ResponseEntity + .status(HttpStatusCode.valueOf(401)) + .body("이메일이 없습니다"); } + return ResponseEntity + .status(HttpStatusCode.valueOf(200)) + .body("회원정보 수정 성공"); + } //회원 조회 - @GetMapping - //TODO: memberID 넣기 - public ResponseEntity> getMemberInfo() { + @GetMapping("/members/") + public ResponseEntity> getMemberInfo(HttpSession session) { Long memberId = 1L; try { Member member = memberService.getMemberById(memberId); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java index c0ecf1c..05d5af5 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java @@ -1,3 +1,4 @@ + package com.codeboy.mvc.controller; import com.codeboy.common.Category; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java index 8b00f96..331eb24 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java @@ -1,7 +1,7 @@ package com.codeboy.mvc.controller; import com.codeboy.mvc.model.dto.UserProblem; -import com.codeboy.mvc.model.responseDto.ApiResponse; // 실제 패키지에 맞게 수정 +import com.codeboy.mvc.model.dto.response.ApiResponse; // 실제 패키지에 맞게 수정 import com.codeboy.mvc.model.service.UserProblemService; import jakarta.servlet.http.HttpSession; import org.slf4j.Logger; @@ -52,7 +52,7 @@ public ResponseEntity> createUserProblems( @RequestBody List userProblems, HttpSession session ) { - Long memberId = (Long) session.getAttribute("member_id"); + Long memberId = (Long) session.getAttribute("memberId"); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); @@ -90,7 +90,7 @@ public ResponseEntity> updateUserProblem( @RequestBody UserProblem userProblem, HttpSession session ) { - Long memberId = (Long) session.getAttribute("member_id"); + Long memberId = (Long) session.getAttribute("memberId"); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); @@ -124,7 +124,7 @@ public ResponseEntity> deleteUserProblem( @PathVariable Long userProblemId, HttpSession session ) { - Long memberId = (Long) session.getAttribute("member_id"); + Long memberId = (Long) session.getAttribute("memberId"); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java index 021943a..6d454af 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java @@ -1,7 +1,7 @@ package com.codeboy.mvc.controller; import com.codeboy.mvc.model.dto.UserProblemSet; -import com.codeboy.mvc.model.responseDto.ApiResponse; // 실제 패키지에 맞게 수정 +import com.codeboy.mvc.model.dto.response.ApiResponse; // 실제 패키지에 맞게 수정 import com.codeboy.mvc.model.service.UserProblemSetService; import jakarta.servlet.http.HttpSession; import org.slf4j.Logger; @@ -39,7 +39,7 @@ public ResponseEntity>> getAllUserProblemSets() // 마이페이지 - 내가 만든 문제세트 조회 @GetMapping("/me") public ResponseEntity> getMyUserProblemSet(HttpSession session) { - Long memberId = (Long) session.getAttribute("member_id"); + Long memberId = (Long) session.getAttribute("memberId"); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); @@ -65,7 +65,7 @@ public ResponseEntity> getMyUserProblemSet(HttpSessi // 마이페이지 - 문제세트 생성 @PostMapping public ResponseEntity> createMyUserProblemSet(HttpSession session) { - Long memberId = (Long) session.getAttribute("member_id"); + Long memberId = (Long) session.getAttribute("memberId"); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); @@ -80,8 +80,9 @@ public ResponseEntity> createMyUserProblemSet(HttpSession sess //UserProblemSetMapper에도 generateKey를 추가해서 PK값을 set에 담을 수 있었다. UserProblemSet set = new UserProblemSet(); set.setMemberId(memberId); - int result = userProblemSetService.createUserProblemSet(set); + System.out.println(set); + int result = userProblemSetService.createUserProblemSet(set); if (result == 0) { return ResponseEntity.status(HttpStatus.BAD_REQUEST) .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "유저 문제세트 생성에 실패했습니다.")); @@ -105,7 +106,7 @@ public ResponseEntity> deleteUserProblemSet( @PathVariable Long userProblemSetId, HttpSession session ) { - Long memberId = (Long) session.getAttribute("member_id"); + Long memberId = (Long) session.getAttribute("memberId"); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java index a82d73c..b1dc5e2 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java @@ -6,7 +6,7 @@ import org.apache.ibatis.annotations.Param; @Mapper public interface MemberDao { - void insertMember(Member member); + int insertMember(Member member); Member selectMemberById(Long memberId); @@ -17,18 +17,22 @@ public interface MemberDao { int updateMemberById(@Param("memberId") Long memberId, @Param("update") MemberUpdateRequest memberUpdateRequest); //아이디 중복 체크 - boolean existsId(String id); + Boolean existsId(String id); //닉네임 중복 체크 - boolean existsNickname(String nickname); + Boolean existsNickname(String nickname); //이메일 중복 체크 - boolean existsEmail(String email); + Boolean existsEmail(String email); //멤버가 활성화 상태인지 확인 - boolean isMemberActive(Long memberId); + Boolean isMemberActive(Long memberId); // 회원 비활성화(탈퇴) - status, isDeleted 업데이트 int deleteMember(long memberId); + // 로그인 - ID와 password로 회원 조회 + Member selectMemberByIdAndPassword(@Param("id") String id, @Param("password") String password); + + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java index e2649b6..3607529 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java @@ -12,7 +12,7 @@ public interface UserProblemSetDao { //마이페이지에서 자신이 제작한 문제세트 조회 - UserProblemSet selectUserProblemSetByMemberId(Long memberId); + UserProblemSet selectUserProblemSetByMemberId(long memberId); //문제 세트 등록 memberId = 문제 제작자만 넘겨주고 문제들은 problemDao에서 insertUserProblem으로 넣음 (마이페이지에서 생성) int insertUserProblemSet(Long memberId); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/IncorrectNote.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/IncorrectNote.java index 25f213d..288ba54 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/IncorrectNote.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/IncorrectNote.java @@ -17,4 +17,5 @@ public class IncorrectNote { private long problemId; private long userProblemId; private Boolean isUserProblem; + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java index 40a8e1e..25f245b 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java @@ -2,6 +2,8 @@ import java.sql.Timestamp; +import com.codeboy.common.Status; + import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Getter; @@ -10,7 +12,8 @@ @NoArgsConstructor @AllArgsConstructor - +@Getter +@Setter @Schema(description="회원 DTO") public class Member { private long memberId; @@ -21,54 +24,8 @@ public class Member { private Timestamp signupDate; private Boolean isActive; private Timestamp deletedDate; - public long getMemberId() { - return memberId; - } - public void setMemberId(long memberId) { - this.memberId = memberId; - } - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - public String getPassword() { - return password; - } - public void setPassword(String password) { - this.password = password; - } - public String getNickname() { - return nickname; - } - public void setNickname(String nickname) { - this.nickname = nickname; - } - public String getEmail() { - return email; - } - public void setEmail(String email) { - this.email = email; - } - public Timestamp getSignupDate() { - return signupDate; - } - public void setSignupDate(Timestamp signupDate) { - this.signupDate = signupDate; - } - public Status getStatus() { - return status; - } - public void setStatus(Status status) { - this.status = status; - } - public Timestamp getDeletedDate() { - return deletedDate; - } - public void setDeletedDate(Timestamp deletedDate) { - this.deletedDate = deletedDate; - } + + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblemSet.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblemSet.java index 723d6af..9a90aa1 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblemSet.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblemSet.java @@ -5,12 +5,14 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import lombok.ToString; @Schema(description = "유저제작문제세트 DTO") @NoArgsConstructor @AllArgsConstructor @Getter @Setter +@ToString public class UserProblemSet { private Long userProblemSetId; private Long memberId; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/LoginRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/LoginRequest.java index f8b12cc..3ddd898 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/LoginRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/LoginRequest.java @@ -1,4 +1,4 @@ -package com.codeboy.mvc.model.requestDto; +package com.codeboy.mvc.model.dto.request; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/ApiResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/ApiResponse.java index 5617ce4..c06d007 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/ApiResponse.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/ApiResponse.java @@ -12,8 +12,17 @@ public class ApiResponse { private HttpStatus status; private String message; private T data; - - public static ApiResponse success(HttpStatus status, T data) { + + + +// public ApiResponse(HttpStatus status, String message, T data) { +// super(); +// this.status = status; +// this.message = message; +// this.data = data; +// } +// + public static ApiResponse success(HttpStatus status, T data) { return new ApiResponse<>(status, null, data); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java deleted file mode 100644 index d191ec4..0000000 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/responseDto/ApiResponse.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.codeboy.mvc.model.responseDto; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.http.HttpStatus; - -@Data -@AllArgsConstructor -@NoArgsConstructor -public class ApiResponse { - private HttpStatus status; - private String message; - private T data; - - public static ApiResponse success(HttpStatus status, T data) { - return new ApiResponse<>(status, null, data); - } - - public static ApiResponse success(HttpStatus status, String message, T data) { - return new ApiResponse<>(status, message, data); - } - - public static ApiResponse failure(HttpStatus status, String message) { - return new ApiResponse<>(status, message, null); - } - -} - - diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java index 9945083..697bd31 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberService.java @@ -1,97 +1,31 @@ package com.codeboy.mvc.model.service; -import com.codeboy.mvc.model.dao.MemberDao; import com.codeboy.mvc.model.dto.Member; import com.codeboy.mvc.model.dto.request.MemberUpdateRequest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import java.util.NoSuchElementException; +public interface MemberService { -@Service -public class MemberService { - @Autowired - MemberDao memberDao; + // 회원정보 조회 + Member getMemberById(Long memberId); - //회원 정보 가져오기기 - public Member getMemberById(Long memberId) { - isMemberExist(memberId); + // 회원 탈퇴 + void deactivateMember(Long memberId); - Member member = memberDao.selectMemberById(memberId); - if (member == null) { - throw new NoSuchElementException("Id에 해당하는 회원 정보를 찾을 수 없습니다. memberId:" + memberId); - } - return member; - }; + // 회원 정보 수정 + void updateMember(Long memberId, MemberUpdateRequest memberUpdateRequest); - //회원 탈퇴 - public void deactivateMember(Long memberId){ - isMemberExist(memberId); + // 중복검사 (ID) + boolean checkIdDuplicate(String id); - int updatedRows = memberDao.deactivateMemberById(memberId); - if (updatedRows == 0) { - throw new IllegalStateException("회원 탈퇴 실패 : memberId: " + memberId); - } - } + // 중복검사 (Nickname) + boolean checkNicknameDuplicate(String nickname); + // 중복검사 (Email) + boolean checkEmailDuplicate(String email); - public void updateMember(Long memberId, MemberUpdateRequest memberUpdateRequest){ - isMemberExist(memberId); - //중복된 id, email이 있는지 검증 로직 - String id = memberUpdateRequest.getId(); - String nickname = memberUpdateRequest.getNickname(); - String email = memberUpdateRequest.getEmail(); - validateMemberUpdate(id, nickname, email); - - int affectedRows = memberDao.updateMemberById(memberId, memberUpdateRequest); - - if (affectedRows == 0) { - throw new IllegalStateException("회원 정보 수정에 실패하였습니다. memberId: " + memberId); - } - - }; - public boolean checkIdDuplicate(String id) { - if (id == null) { - throw new IllegalArgumentException("유효하지 않은 Id 입니다."); - } - return memberDao.existsId(id); - } - - public boolean checkNicknameDuplicate(String nickname ) { - if (nickname == null) { - throw new IllegalArgumentException("유효하지 않은 Id 입니다."); - } - return memberDao.existsNickname(nickname); - } - - public boolean checkEmailDuplicate(String email) { - if (email == null) { - throw new IllegalArgumentException("유효하지 않은 Id 입니다."); - } - return memberDao.existsEmail(email); - } - public void isMemberExist(Long memberId) { - if (memberId == null) { - throw new IllegalArgumentException("유효하지 않은 memberId입니다. memberId: " ); - } - - boolean isActive = memberDao.isMemberActive(memberId); - if (!isActive) { - throw new IllegalArgumentException("비활성화된 멤버 id 입니다. memberId: " + memberId); - } - } - - // 최종 제출 시 전체 검증 - public void validateMemberUpdate(String id, String nickname, String email) { - if (memberDao.existsId(id)) { - throw new IllegalArgumentException("중복된 ID입니다."); - } - if (memberDao.existsNickname(nickname)) { - throw new IllegalArgumentException("중복된 닉네임입니다."); - } - if (memberDao.existsEmail(email)) { - throw new IllegalArgumentException("중복된 이메일입니다."); - } - } - -}; + int signUp(Member member); + + + // 로그인 + Member login(String id, String password); +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java index a003e65..8929d4b 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java @@ -1,48 +1,118 @@ package com.codeboy.mvc.model.service; -import java.sql.Timestamp; -import java.time.LocalDateTime; - +import com.codeboy.mvc.model.dao.MemberDao; +import com.codeboy.mvc.model.dto.Member; +import com.codeboy.mvc.model.dto.request.MemberUpdateRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.codeboy.mvc.model.dao.MemberDao; -import com.codeboy.mvc.model.dto.Member; -import com.codeboy.common.Status; +import java.util.NoSuchElementException; @Service public class MemberServiceImpl implements MemberService { + @Autowired + MemberDao memberDao; - private final MemberDao memberDao; + //회원 정보 가져오기기 + public Member getMemberById(Long memberId) { + isMemberExist(memberId); - @Autowired - public MemberServiceImpl(MemberDao memberDao) { - this.memberDao = memberDao; + Member member = memberDao.selectMemberById(memberId); + if (member == null) { + throw new NoSuchElementException("Id에 해당하는 회원 정보를 찾을 수 없습니다. memberId:" + memberId); + } + return member; + }; + + //회원 탈퇴 + public void deactivateMember(Long memberId){ + isMemberExist(memberId); + + int updatedRows = memberDao.deactivateMemberById(memberId); + if (updatedRows == 0) { + throw new IllegalStateException("회원 탈퇴 실패 : memberId: " + memberId); + } + } + + + public void updateMember(Long memberId, MemberUpdateRequest memberUpdateRequest){ + isMemberExist(memberId); + //중복된 id, email이 있는지 검증 로직 + String id = memberUpdateRequest.getId(); + String nickname = memberUpdateRequest.getNickname(); + String email = memberUpdateRequest.getEmail(); + validateMemberUpdate(id, nickname, email); + + int affectedRows = memberDao.updateMemberById(memberId, memberUpdateRequest); + + if (affectedRows == 0) { + throw new IllegalStateException("회원 정보 수정에 실패하였습니다. memberId: " + memberId); + } + + }; + public boolean checkIdDuplicate(String id) { + if (id == null) { + throw new IllegalArgumentException("유효하지 않은 Id 입니다."); + } + return memberDao.existsId(id); + } + + public boolean checkNicknameDuplicate(String nickname ) { + if (nickname == null) { + throw new IllegalArgumentException("유효하지 않은 Id 입니다."); + } + return memberDao.existsNickname(nickname); + } + + public boolean checkEmailDuplicate(String email) { + if (email == null) { + throw new IllegalArgumentException("유효하지 않은 Id 입니다."); + } + return memberDao.existsEmail(email); } @Override public int signUp(Member member) { - // 기본값 세팅 - member.setStatus(Status.ACTIVE); - member.setDeletedDate(null); - member.setSignupDate(Timestamp.valueOf(LocalDateTime.now())); return memberDao.insertMember(member); } - @Override - public Member getMemberByMemberId(long memberId) { - return memberDao.selectMemberByMemberId(memberId); + public void isMemberExist(Long memberId) { + if (memberId == null) { + throw new IllegalArgumentException("유효하지 않은 memberId입니다. memberId: " ); + } + + boolean isActive = memberDao.isMemberActive(memberId); + if (!isActive) { + throw new IllegalArgumentException("비활성화된 멤버 id 입니다. memberId: " + memberId); + } } - - @Override - public int updateMember(long memberId, Member member) { + // 최종 제출 시 전체 검증 + public void validateMemberUpdate(String id, String nickname, String email) { + if (memberDao.existsId(id)) { + throw new IllegalArgumentException("중복된 ID입니다."); + } + if (memberDao.existsNickname(nickname)) { + throw new IllegalArgumentException("중복된 닉네임입니다."); + } + if (memberDao.existsEmail(email)) { + throw new IllegalArgumentException("중복된 이메일입니다."); + } + } + + // 로그인 + public Member login(String id, String password) { + if (id == null || password == null) { + throw new IllegalArgumentException("ID와 비밀번호를 입력해주세요."); + } - return memberDao.updateMember(memberId, member); + Member member = memberDao.selectMemberByIdAndPassword(id, password); + if (member == null) { + throw new IllegalArgumentException("ID 또는 비밀번호가 올바르지 않습니다."); + } + + return member; } + - @Override - public int deactivateMember(long memberId) { - return memberDao.deleteMember(memberId); - } -} +}; \ No newline at end of file diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java index 710c837..38ead0c 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java @@ -30,4 +30,5 @@ public List getProblems(int limit, Category category) { return problems; } + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetServiceImpl.java index 3d10892..4d15576 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetServiceImpl.java @@ -23,7 +23,8 @@ public List getAllUserProblemSets() { @Override public UserProblemSet getUserProblemSetByMemberId(Long memberId) { - return userProblemSetDao.selectUserProblemSetByMemberId(memberId); + long memberIdl = memberId; + return userProblemSetDao.selectUserProblemSetByMemberId(memberIdl); } @Override @@ -31,7 +32,8 @@ public int createUserProblemSet(UserProblemSet set) { if (set.getMemberId() == null) { throw new IllegalArgumentException("회원 ID가 필요합니다."); } - return userProblemSetDao.insertUserProblemSet(set.getMemberId()); + long memberId = set.getMemberId(); + return userProblemSetDao.insertUserProblemSet(memberId); } @Override diff --git a/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml b/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml index eca08ca..21c1d0f 100644 --- a/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/CommentMapper.xml @@ -2,22 +2,23 @@ + - SELECT * FROM comment - WHERE user_problem_id = #{userProblemSetId} + WHERE user_problem_set_id = #{userProblemSetId} - INSERT INTO comment (member_id, content, comment_date, user_problem_set) - VALUES (#{member_id}, #{content}, #{comment_date, #{user_problem_set}) + INSERT INTO comment (member_id, content, comment_date, user_problem_set_id) + VALUES (#{comment.memberId}, #{comment.content}, NOW(), #{userProblemSetId}) UPDATE comment - SET content = #{content} + SET content = #{comment.content} WHERE comment_id = #{commentId} @@ -26,8 +27,12 @@ FROM comment WHERE comment_id = #{commentId} + + + - diff --git a/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml index 871c4ec..d253890 100644 --- a/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml @@ -35,7 +35,7 @@ + + + INSERT INTO member (ID, password, nickname, email, is_active, signup_date) + VALUES (#{id}, #{password}, #{nickname}, #{email}, 1, NOW()); + + + + From cf028d9ee3f87fdd96c973abe90e4b10dbc56e30 Mon Sep 17 00:00:00 2001 From: junhyung8795 Date: Tue, 2 Dec 2025 14:25:22 +0900 Subject: [PATCH 31/61] =?UTF-8?q?test:=20QuizRoom=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EA=B3=BC=20UserScore=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=B6=94=EA=B0=80=20=ED=9B=84=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B2=B0=EA=B3=BC=20=EB=AC=B8=EC=A0=9C=EC=84=B8?= =?UTF-8?q?=ED=8A=B8=20=EC=83=9D=EC=84=B1=20(500)=20-=20=EC=84=9C=EB=B2=84?= =?UTF-8?q?=20=EC=98=A4=EB=A5=98=20=EB=8C=93=EA=B8=80=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20(403)=20-=20=EA=B6=8C=ED=95=9C=20=EB=AC=B8=EC=A0=9C=20(?= =?UTF-8?q?=EB=B3=B8=EC=9D=B8=20=EB=8C=93=EA=B8=80=EB=A7=8C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EA=B0=80=EB=8A=A5)=20->=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=8B=9C=EB=82=98=EB=A6=AC=EC=98=A4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=98=88=EC=A0=95.=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20(400)=20-=20limit=20=EA=B0=92=EC=9D=B4=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=EC=88=98=EB=B3=B4=EB=8B=A4=20=ED=81=BC=20?= =?UTF-8?q?->=20limit=EA=B4=80=EB=A0=A8=20=EB=A1=9C=EC=A7=81=EC=9D=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=EB=8F=BC=EC=9E=88=EC=9D=8C=EC=97=90=EB=8F=84?= =?UTF-8?q?=20=EB=AC=B8=EC=A0=9C=EA=B0=80=20=EC=9E=88=EC=9D=8C.=20?= =?UTF-8?q?=ED=80=B4=EC=A6=88=EB=B0=A9=20=EB=A9=A4=EB=B2=84=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20(400)=20-=20=EC=B0=B8=EA=B0=80=EC=9E=90=EA=B0=80=20?= =?UTF-8?q?=EC=97=86=EC=9D=8C=20->=20=ED=80=B4=EC=A6=88=EB=B0=A9=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=A0=84=EC=97=90=20=ED=80=B4=EC=A6=88?= =?UTF-8?q?=EB=B0=A9=20=EB=A9=A4=EB=B2=84=EB=A5=BC=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=ED=95=98=EB=A0=A4=ED=95=B4=EC=84=9C=20=EB=9C=A8=EB=8A=94=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC.=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=8B=9C?= =?UTF-8?q?=EB=82=98=EB=A6=AC=EC=98=A4=20=EC=88=98=EC=A0=95=20=EC=98=88?= =?UTF-8?q?=EC=A0=95.=20=ED=80=B4=EC=A6=88=EB=B0=A9=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=20(500)=20-=20=EC=99=B8=EB=9E=98=ED=82=A4=20=EC=A0=9C=EC=95=BD?= =?UTF-8?q?=20=EC=A1=B0=EA=B1=B4=20->=20=EC=99=B8=EB=9E=98=ED=82=A4=20?= =?UTF-8?q?=EC=A0=9C=EC=95=BD=EC=A1=B0=EA=B1=B4=EC=9D=B4=20=EC=9E=88?= =?UTF-8?q?=EC=96=B4=20ON=20DELETE=20CASCADE=EC=A0=9C=EC=95=BD=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=20=EC=B6=94=EA=B0=80=EC=98=88=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mvc/controller/QuizRoomController.java | 6 +- .../mvc/controller/UserScoreController.java | 161 ++++++++++++++++++ .../com/codeboy/mvc/model/dao/ScoreDao.java | 21 --- .../codeboy/mvc/model/dao/UserScoreDao.java | 21 +++ .../com/codeboy/mvc/model/dto/UserScore.java | 2 - .../mvc/model/service/ScoreService.java | 5 - .../mvc/model/service/UserScoreService.java | 23 +++ .../model/service/UserScoreServiceImpl.java | 72 ++++++++ .../main/resources/mappers/ScoreMapper.xml | 8 - .../resources/mappers/UserScoreMapper.xml | 29 ++++ 10 files changed, 310 insertions(+), 38 deletions(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java delete mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ScoreDao.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserScoreDao.java delete mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ScoreService.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserScoreService.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserScoreServiceImpl.java delete mode 100644 codeBoy_backend/src/main/resources/mappers/ScoreMapper.xml create mode 100644 codeBoy_backend/src/main/resources/mappers/UserScoreMapper.xml diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java index 28656d1..f892631 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java @@ -5,6 +5,7 @@ import com.codeboy.mvc.model.dto.response.ApiResponse; import com.codeboy.mvc.model.dto.response.GetQuizRoomMembersResponse; import com.codeboy.mvc.model.service.QuizRoomService; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -13,6 +14,7 @@ @RestController @RequestMapping("/api/quiz-room") +@Tag(name="Quiz-room RESTful API", description = "Quiz-room CRUD를 할 수 있는 REST API") public class QuizRoomController { private final QuizRoomService quizRoomService; @@ -40,7 +42,7 @@ public ResponseEntity> createQuizRoom(@PathVariable long membe quizRoomService.joinQuizRoom(quizRoomMember); return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(HttpStatus.CREATED, "퀴즈방이 성공적으로 생성되었습니다.", quizRoomId)); - } catch (IllegalStateException e) { + } catch (IllegalStateException | IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); } } @@ -102,4 +104,4 @@ public ResponseEntity> deleteQuizRoom(@PathVariable long roo return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); } } -} +} \ No newline at end of file diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java new file mode 100644 index 0000000..d2abb2b --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java @@ -0,0 +1,161 @@ +package com.codeboy.mvc.controller; + +import java.util.List; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import com.codeboy.mvc.model.dto.UserScore; +import com.codeboy.mvc.model.service.UserScoreService; +import com.codeboy.mvc.model.dto.response.ApiResponse; + +import jakarta.servlet.http.HttpSession; + +@RestController +@RequestMapping("api/scores") +public class UserScoreController { + + private final UserScoreService userScoreService; + + public UserScoreController(UserScoreService userScoreService) { + this.userScoreService = userScoreService; + } + + // 점수 등록 + @PostMapping + public ResponseEntity> createUserScore( + @RequestBody UserScore userScore, + HttpSession session + ) { + Long memberId = (Long) session.getAttribute("memberId"); + if (memberId == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); + } + + // 세션의 memberId를 강제로 DTO에 세팅 (신뢰할 수 있는 값) + userScore.setMemberId(memberId); + + try { + int result = userScoreService.registerScore(userScore); + + if (result == 0) { + // SQL은 정상 실행되었지만, 반영된 row가 없음 + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "SQL이 실행됐으나 row가 반영되지 않았습니다.")); + } + + return ResponseEntity.status(HttpStatus.CREATED) + .body(ApiResponse.success(HttpStatus.CREATED, "점수 등록 성공", null)); + + } catch (IllegalArgumentException e) { + // 파라미터/입력 문제 + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + + } catch (Exception e) { + // 예기치 못한 DB 오류 / 서버 오류 + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "서버 오류로 점수를 등록하지 못했습니다.")); + } + } + + // 전체 유저 점수 조회 + @GetMapping + public ResponseEntity>> getAllUserScores(HttpSession session) { + Long memberId = (Long) session.getAttribute("memberId"); + if (memberId == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); + } + + try { + List scores = userScoreService.getAllUserScores(); + + if (scores == null || scores.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(ApiResponse.failure(HttpStatus.NOT_FOUND, "점수 목록이 비어있습니다. UserScore테이블을 확인해주세요.")); + } + + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "점수 목록 조회 성공", scores)); + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "서버 오류로 점수 목록을 조회하지 못했습니다.")); + } + } + + // 특정 유저 점수 조회 + @GetMapping("/{memberId}") + public ResponseEntity> getUserScore( + @PathVariable Long memberId, + HttpSession session + ) { + Long loginMemberId = (Long) session.getAttribute("memberId"); + if (loginMemberId == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); + } + + + + try { + UserScore userScore = userScoreService.getUserScoreById(memberId); + + if (userScore == null) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(ApiResponse.failure(HttpStatus.NOT_FOUND, "해당 회원의 점수가 존재하지 않습니다.")); + } + + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "점수 조회 성공", userScore)); + + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "서버 오류로 점수를 조회하지 못했습니다.")); + } + } + + // 점수 수정 HttpSession에서 memberId를 가져와 이 사람의 점수를 갱신하는거라 PathVariable이나 @RequestBody가 없다. + @PutMapping + public ResponseEntity> updateUserScore( + @RequestBody UserScore userScore, + HttpSession session + ) { + Long memberId = (Long) session.getAttribute("memberId"); + if (memberId == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); + } + + // 세션 기준으로 memberId 강제 세팅 + userScore.setMemberId(memberId); + + try { + int result = userScoreService.updateUser(userScore); + + if (result == 0) { + // 수정할 row가 없거나, 업데이트 실패 + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "점수 수정에 실패했습니다.")); + } + + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "점수 수정 성공", null)); + + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "서버 오류로 점수를 수정하지 못했습니다.")); + } + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ScoreDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ScoreDao.java deleted file mode 100644 index f61f3ab..0000000 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ScoreDao.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.codeboy.mvc.model.dao; - -import java.util.List; - -import com.codeboy.mvc.model.dto.UserScore; - -public interface ScoreDao { - //스코어 등록 - public void insertScore(UserScore userScore); - - //모든 스코어 조회 - public List selectAllUserScore(); - - //한 멤버의 스코어 조회 - public int selectOneUserScore(Long memberId); - - //멤버 스코어 업데이트 - public void updateUserScore(UserScore userScore); - - -} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserScoreDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserScoreDao.java new file mode 100644 index 0000000..4f67e0b --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserScoreDao.java @@ -0,0 +1,21 @@ +package com.codeboy.mvc.model.dao; + +import java.util.List; + +import com.codeboy.mvc.model.dto.UserScore; + +public interface UserScoreDao { + //스코어 등록 + public int insertScore(UserScore userScore); + + //모든 스코어 조회 + public List selectAllUserScores(); + + //한 멤버의 스코어 조회 + public UserScore selectOneUserScore(Long memberId); + + //멤버 스코어 업데이트 + public int updateUserScore(UserScore userScore); + + +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserScore.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserScore.java index 03c3747..6a323ad 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserScore.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserScore.java @@ -15,6 +15,4 @@ public class UserScore { private long memberId; private int score; - - } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ScoreService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ScoreService.java deleted file mode 100644 index 2b2aa4c..0000000 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ScoreService.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.codeboy.mvc.model.service; - -public class ScoreService { - -} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserScoreService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserScoreService.java new file mode 100644 index 0000000..2f07894 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserScoreService.java @@ -0,0 +1,23 @@ +package com.codeboy.mvc.model.service; + +import java.util.List; + +import com.codeboy.mvc.model.dto.UserScore; + +public interface UserScoreService { + + + //회원가입 시 자동으로 리더보드에 보여줄 점수를 등록 디폴트는 0 + int registerScore(UserScore userScore); + + //리더보드에 모든 유저들의 점수정보들을 보여줌 + List getAllUserScores(); + + //한 멤버의 스코어 조회 + UserScore getUserScoreById(Long memberId); + + //멤버 스코어 업데이트 + //업데이트된 행 수 반환 + int updateUser(UserScore userScore); + +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserScoreServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserScoreServiceImpl.java new file mode 100644 index 0000000..eea3262 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserScoreServiceImpl.java @@ -0,0 +1,72 @@ +package com.codeboy.mvc.model.service; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.codeboy.mvc.model.dao.UserScoreDao; +import com.codeboy.mvc.model.dto.UserScore; + + +@Service +public class UserScoreServiceImpl implements UserScoreService { + + private final UserScoreDao userScoreDao; + + public UserScoreServiceImpl(UserScoreDao userScoreDao) { + this.userScoreDao = userScoreDao; + } + + @Override + public int registerScore(UserScore userScore) { + // 1. 파라미터 유효성 검증 → IllegalArgumentException + if (userScore == null) { + throw new IllegalArgumentException("점수 정보가 비어 있습니다."); + } + if (userScore.getMemberId() <= 0) { + throw new IllegalArgumentException("유효하지 않은 회원 ID입니다."); + } + if (userScore.getScore() < 0) { + throw new IllegalArgumentException("점수는 0 이상이어야 합니다."); + } + + // 2. DAO 호출 → 삽입된 row 수 반환 + int result = userScoreDao.insertScore(userScore); + // result가 0인지 아닌지는 컨트롤러에서 판단 + return result; + } + + @Override + public List getAllUserScores() { + // 여기서는 그냥 DAO 결과를 그대로 반환하고 + // 목록이 비었는지 여부는 컨트롤러에서 판단함. + return userScoreDao.selectAllUserScores(); + } + + @Override + public UserScore getUserScoreById(Long memberId) { + if (memberId == null || memberId <= 0) { + throw new IllegalArgumentException("유효하지 않은 회원 ID입니다."); + } + + // 없으면 null 반환 → 컨트롤러에서 404 처리 + return userScoreDao.selectOneUserScore(memberId); + } + + @Override + public int updateUser(UserScore userScore) { + if (userScore == null) { + throw new IllegalArgumentException("점수 정보가 비어 있습니다."); + } + if (userScore.getMemberId() <= 0) { + throw new IllegalArgumentException("유효하지 않은 회원 ID입니다."); + } + if (userScore.getScore() < 0) { + throw new IllegalArgumentException("점수는 0 이상이어야 합니다."); + } + + int result = userScoreDao.updateUserScore(userScore); + return result; + } +} + diff --git a/codeBoy_backend/src/main/resources/mappers/ScoreMapper.xml b/codeBoy_backend/src/main/resources/mappers/ScoreMapper.xml deleted file mode 100644 index d0b38ce..0000000 --- a/codeBoy_backend/src/main/resources/mappers/ScoreMapper.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/codeBoy_backend/src/main/resources/mappers/UserScoreMapper.xml b/codeBoy_backend/src/main/resources/mappers/UserScoreMapper.xml new file mode 100644 index 0000000..f40b22f --- /dev/null +++ b/codeBoy_backend/src/main/resources/mappers/UserScoreMapper.xml @@ -0,0 +1,29 @@ + + + + + + + INSERT INTO user_score(member_id, score) + VALUES(#{memberId}, #{score}) + + + + + + + + UPDATE user_score + SET score = #{score} + WHERE member_id = #{memberId} + + + From 9c9c32a6ea0a4c3cc26b3ed575ae985eb1d5cf9d Mon Sep 17 00:00:00 2001 From: junhyung8795 Date: Tue, 2 Dec 2025 14:53:24 +0900 Subject: [PATCH 32/61] =?UTF-8?q?.class=20=EB=93=B1=20=EC=B6=94=EC=A0=81?= =?UTF-8?q?=EB=90=98=EB=A9=B4=20=EC=95=88=EB=90=98=EB=8A=94=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EB=93=A4=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .classpath | 44 --- .project | 34 -- .settings/org.eclipse.jdt.apt.core.prefs | 2 - .settings/org.eclipse.jdt.core.prefs | 12 - .settings/org.eclipse.m2e.core.prefs | 4 - ....eclipse.wst.common.project.facet.core.xml | 4 - .../org.springframework.ide.eclipse.prefs | 2 - .../codeboy/CodeBoyBackendApplication.class | Bin 839 -> 0 bytes .../CodeBoyBackendApplicationTests.class | Bin 838 -> 0 bytes bin/com/codeboy/common/Category.class | Bin 1015 -> 0 bytes bin/com/codeboy/common/Status.class | Bin 996 -> 0 bytes .../codeboy/mvc/config/SwaggerConfig.class | Bin 1644 -> 0 bytes .../mvc/controller/MemberController.class | Bin 1396 -> 0 bytes .../codeboy/mvc/model/dao/CommentDao.class | Bin 379 -> 0 bytes .../mvc/model/dao/IncorrectNoteDao.class | Bin 348 -> 0 bytes bin/com/codeboy/mvc/model/dao/MemberDao.class | Bin 387 -> 0 bytes .../codeboy/mvc/model/dao/ProblemDao.class | Bin 308 -> 0 bytes .../codeboy/mvc/model/dao/QuizRoomDao.class | Bin 525 -> 0 bytes bin/com/codeboy/mvc/model/dao/ScoreDao.class | Bin 380 -> 0 bytes .../mvc/model/dao/UserIncorrectNoteDao.class | Bin 372 -> 0 bytes .../mvc/model/dao/UserProblemDao.class | Bin 628 -> 0 bytes bin/com/codeboy/mvc/model/dto/Comment.class | Bin 1086 -> 0 bytes .../codeboy/mvc/model/dto/IncorrectNote.class | Bin 1019 -> 0 bytes bin/com/codeboy/mvc/model/dto/Member.class | Bin 1153 -> 0 bytes .../mvc/model/dto/MemberUpdateRequest.class | Bin 1037 -> 0 bytes bin/com/codeboy/mvc/model/dto/Problem.class | Bin 1146 -> 0 bytes bin/com/codeboy/mvc/model/dto/QuizRoom.class | Bin 956 -> 0 bytes .../mvc/model/dto/QuizRoomMember.class | Bin 1059 -> 0 bytes .../mvc/model/dto/UserIncorrectNote.class | Bin 1039 -> 0 bytes .../codeboy/mvc/model/dto/UserProblem.class | Bin 1216 -> 0 bytes .../mvc/model/dto/UserProblemSet.class | Bin 1003 -> 0 bytes bin/com/codeboy/mvc/model/dto/UserScore.class | Bin 981 -> 0 bytes .../mvc/model/service/CommentService.class | Bin 327 -> 0 bytes .../model/service/IncorrectNoteService.class | Bin 345 -> 0 bytes .../mvc/model/service/MemberService.class | Bin 367 -> 0 bytes .../mvc/model/service/ProblemService.class | Bin 327 -> 0 bytes .../mvc/model/service/QuizRoomService.class | Bin 639 -> 0 bytes .../model/service/QuizRoomServiceImpl.class | Bin 1135 -> 0 bytes .../mvc/model/service/ScoreService.class | Bin 321 -> 0 bytes .../model/service/UserProblemService.class | Bin 339 -> 0 bytes .../.mvn/wrapper/maven-wrapper.properties | 3 - codeBoy_backend/mvnw | 295 ------------------ codeBoy_backend/mvnw.cmd | 189 ----------- codeBoy_backend/pom.xml | 113 ------- .../src/main/resources/application.properties | 24 -- pom.xml | 19 -- target/classes/META-INF/MANIFEST.MF | 4 - .../maven/Backend/Backend/pom.properties | 7 - .../META-INF/maven/Backend/Backend/pom.xml | 19 -- .../codeboy/CodeBoyBackendApplication.class | Bin 723 -> 0 bytes .../classes/com/codeboy/common/Category.class | Bin 1015 -> 0 bytes .../classes/com/codeboy/common/Status.class | Bin 996 -> 0 bytes .../codeboy/mvc/config/SwaggerConfig.class | Bin 1317 -> 0 bytes .../mvc/controller/MemberController.class | Bin 1177 -> 0 bytes .../codeboy/mvc/model/dao/CommentDao.class | Bin 379 -> 0 bytes .../mvc/model/dao/IncorrectNoteDao.class | Bin 348 -> 0 bytes .../com/codeboy/mvc/model/dao/MemberDao.class | Bin 387 -> 0 bytes .../codeboy/mvc/model/dao/ProblemDao.class | Bin 308 -> 0 bytes .../codeboy/mvc/model/dao/QuizRoomDao.class | Bin 525 -> 0 bytes .../com/codeboy/mvc/model/dao/ScoreDao.class | Bin 380 -> 0 bytes .../mvc/model/dao/UserIncorrectNoteDao.class | Bin 372 -> 0 bytes .../mvc/model/dao/UserProblemDao.class | Bin 628 -> 0 bytes .../com/codeboy/mvc/model/dto/Comment.class | Bin 1105 -> 0 bytes .../codeboy/mvc/model/dto/IncorrectNote.class | Bin 1045 -> 0 bytes .../com/codeboy/mvc/model/dto/Member.class | Bin 1172 -> 0 bytes .../mvc/model/dto/MemberUpdateRequest.class | Bin 1070 -> 0 bytes .../com/codeboy/mvc/model/dto/Problem.class | Bin 1172 -> 0 bytes .../com/codeboy/mvc/model/dto/QuizRoom.class | Bin 978 -> 0 bytes .../mvc/model/dto/QuizRoomMember.class | Bin 1095 -> 0 bytes .../mvc/model/dto/UserIncorrectNote.class | Bin 1076 -> 0 bytes .../codeboy/mvc/model/dto/UserProblem.class | Bin 1241 -> 0 bytes .../mvc/model/dto/UserProblemSet.class | Bin 1040 -> 0 bytes .../com/codeboy/mvc/model/dto/UserScore.class | Bin 1000 -> 0 bytes .../mvc/model/service/CommentService.class | Bin 327 -> 0 bytes .../model/service/IncorrectNoteService.class | Bin 345 -> 0 bytes .../mvc/model/service/MemberService.class | Bin 367 -> 0 bytes .../mvc/model/service/ProblemService.class | Bin 327 -> 0 bytes .../mvc/model/service/QuizRoomService.class | Bin 639 -> 0 bytes .../model/service/QuizRoomServiceImpl.class | Bin 1035 -> 0 bytes .../mvc/model/service/ScoreService.class | Bin 321 -> 0 bytes .../model/service/UserProblemService.class | Bin 339 -> 0 bytes .../CodeBoyBackendApplicationTests.class | Bin 551 -> 0 bytes 82 files changed, 775 deletions(-) delete mode 100644 .classpath delete mode 100644 .project delete mode 100644 .settings/org.eclipse.jdt.apt.core.prefs delete mode 100644 .settings/org.eclipse.jdt.core.prefs delete mode 100644 .settings/org.eclipse.m2e.core.prefs delete mode 100644 .settings/org.eclipse.wst.common.project.facet.core.xml delete mode 100644 .settings/org.springframework.ide.eclipse.prefs delete mode 100644 bin/com/codeboy/CodeBoyBackendApplication.class delete mode 100644 bin/com/codeboy/CodeBoyBackendApplicationTests.class delete mode 100644 bin/com/codeboy/common/Category.class delete mode 100644 bin/com/codeboy/common/Status.class delete mode 100644 bin/com/codeboy/mvc/config/SwaggerConfig.class delete mode 100644 bin/com/codeboy/mvc/controller/MemberController.class delete mode 100644 bin/com/codeboy/mvc/model/dao/CommentDao.class delete mode 100644 bin/com/codeboy/mvc/model/dao/IncorrectNoteDao.class delete mode 100644 bin/com/codeboy/mvc/model/dao/MemberDao.class delete mode 100644 bin/com/codeboy/mvc/model/dao/ProblemDao.class delete mode 100644 bin/com/codeboy/mvc/model/dao/QuizRoomDao.class delete mode 100644 bin/com/codeboy/mvc/model/dao/ScoreDao.class delete mode 100644 bin/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.class delete mode 100644 bin/com/codeboy/mvc/model/dao/UserProblemDao.class delete mode 100644 bin/com/codeboy/mvc/model/dto/Comment.class delete mode 100644 bin/com/codeboy/mvc/model/dto/IncorrectNote.class delete mode 100644 bin/com/codeboy/mvc/model/dto/Member.class delete mode 100644 bin/com/codeboy/mvc/model/dto/MemberUpdateRequest.class delete mode 100644 bin/com/codeboy/mvc/model/dto/Problem.class delete mode 100644 bin/com/codeboy/mvc/model/dto/QuizRoom.class delete mode 100644 bin/com/codeboy/mvc/model/dto/QuizRoomMember.class delete mode 100644 bin/com/codeboy/mvc/model/dto/UserIncorrectNote.class delete mode 100644 bin/com/codeboy/mvc/model/dto/UserProblem.class delete mode 100644 bin/com/codeboy/mvc/model/dto/UserProblemSet.class delete mode 100644 bin/com/codeboy/mvc/model/dto/UserScore.class delete mode 100644 bin/com/codeboy/mvc/model/service/CommentService.class delete mode 100644 bin/com/codeboy/mvc/model/service/IncorrectNoteService.class delete mode 100644 bin/com/codeboy/mvc/model/service/MemberService.class delete mode 100644 bin/com/codeboy/mvc/model/service/ProblemService.class delete mode 100644 bin/com/codeboy/mvc/model/service/QuizRoomService.class delete mode 100644 bin/com/codeboy/mvc/model/service/QuizRoomServiceImpl.class delete mode 100644 bin/com/codeboy/mvc/model/service/ScoreService.class delete mode 100644 bin/com/codeboy/mvc/model/service/UserProblemService.class delete mode 100644 codeBoy_backend/.mvn/wrapper/maven-wrapper.properties delete mode 100644 codeBoy_backend/mvnw delete mode 100644 codeBoy_backend/mvnw.cmd delete mode 100644 codeBoy_backend/pom.xml delete mode 100644 codeBoy_backend/src/main/resources/application.properties delete mode 100644 pom.xml delete mode 100644 target/classes/META-INF/MANIFEST.MF delete mode 100644 target/classes/META-INF/maven/Backend/Backend/pom.properties delete mode 100644 target/classes/META-INF/maven/Backend/Backend/pom.xml delete mode 100644 target/classes/com/codeboy/CodeBoyBackendApplication.class delete mode 100644 target/classes/com/codeboy/common/Category.class delete mode 100644 target/classes/com/codeboy/common/Status.class delete mode 100644 target/classes/com/codeboy/mvc/config/SwaggerConfig.class delete mode 100644 target/classes/com/codeboy/mvc/controller/MemberController.class delete mode 100644 target/classes/com/codeboy/mvc/model/dao/CommentDao.class delete mode 100644 target/classes/com/codeboy/mvc/model/dao/IncorrectNoteDao.class delete mode 100644 target/classes/com/codeboy/mvc/model/dao/MemberDao.class delete mode 100644 target/classes/com/codeboy/mvc/model/dao/ProblemDao.class delete mode 100644 target/classes/com/codeboy/mvc/model/dao/QuizRoomDao.class delete mode 100644 target/classes/com/codeboy/mvc/model/dao/ScoreDao.class delete mode 100644 target/classes/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.class delete mode 100644 target/classes/com/codeboy/mvc/model/dao/UserProblemDao.class delete mode 100644 target/classes/com/codeboy/mvc/model/dto/Comment.class delete mode 100644 target/classes/com/codeboy/mvc/model/dto/IncorrectNote.class delete mode 100644 target/classes/com/codeboy/mvc/model/dto/Member.class delete mode 100644 target/classes/com/codeboy/mvc/model/dto/MemberUpdateRequest.class delete mode 100644 target/classes/com/codeboy/mvc/model/dto/Problem.class delete mode 100644 target/classes/com/codeboy/mvc/model/dto/QuizRoom.class delete mode 100644 target/classes/com/codeboy/mvc/model/dto/QuizRoomMember.class delete mode 100644 target/classes/com/codeboy/mvc/model/dto/UserIncorrectNote.class delete mode 100644 target/classes/com/codeboy/mvc/model/dto/UserProblem.class delete mode 100644 target/classes/com/codeboy/mvc/model/dto/UserProblemSet.class delete mode 100644 target/classes/com/codeboy/mvc/model/dto/UserScore.class delete mode 100644 target/classes/com/codeboy/mvc/model/service/CommentService.class delete mode 100644 target/classes/com/codeboy/mvc/model/service/IncorrectNoteService.class delete mode 100644 target/classes/com/codeboy/mvc/model/service/MemberService.class delete mode 100644 target/classes/com/codeboy/mvc/model/service/ProblemService.class delete mode 100644 target/classes/com/codeboy/mvc/model/service/QuizRoomService.class delete mode 100644 target/classes/com/codeboy/mvc/model/service/QuizRoomServiceImpl.class delete mode 100644 target/classes/com/codeboy/mvc/model/service/ScoreService.class delete mode 100644 target/classes/com/codeboy/mvc/model/service/UserProblemService.class delete mode 100644 target/test-classes/com/codeboy/CodeBoyBackendApplicationTests.class diff --git a/.classpath b/.classpath deleted file mode 100644 index dea924c..0000000 --- a/.classpath +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.project b/.project deleted file mode 100644 index cb29ace..0000000 --- a/.project +++ /dev/null @@ -1,34 +0,0 @@ - - - Backend - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.wst.common.project.facet.core.builder - - - - - org.springframework.ide.eclipse.boot.validation.springbootbuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.m2e.core.maven2Nature - org.eclipse.wst.common.project.facet.core.nature - org.eclipse.jdt.core.javanature - - diff --git a/.settings/org.eclipse.jdt.apt.core.prefs b/.settings/org.eclipse.jdt.apt.core.prefs deleted file mode 100644 index d4313d4..0000000 --- a/.settings/org.eclipse.jdt.apt.core.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.apt.aptEnabled=false diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index e82d82e..0000000 --- a/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,12 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 -org.eclipse.jdt.core.compiler.compliance=17 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.processAnnotations=disabled -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=17 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml deleted file mode 100644 index 48ff4f3..0000000 --- a/.settings/org.eclipse.wst.common.project.facet.core.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/.settings/org.springframework.ide.eclipse.prefs b/.settings/org.springframework.ide.eclipse.prefs deleted file mode 100644 index a12794d..0000000 --- a/.settings/org.springframework.ide.eclipse.prefs +++ /dev/null @@ -1,2 +0,0 @@ -boot.validation.initialized=true -eclipse.preferences.version=1 diff --git a/bin/com/codeboy/CodeBoyBackendApplication.class b/bin/com/codeboy/CodeBoyBackendApplication.class deleted file mode 100644 index ad03b8e5e31134a436212e6adcda934e19956bf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 839 zcmbVK(P|Sx6g`usO|nK)qixlKj1SV(hvubE#tMz72#bQL1@UQiGp5t-&Ru3Fk$jn8 zLErrhKSaE*2zXU{z|=broh=a;Vl_ORJNP2gclc|WDGPH5hL#(7Bdp-NA* z9q$)KW>V!1*#_zYtH)}l`kAtm{+r}jr(R&?iLu5%6AZX_qt?NZmL@OAc}Z@vQx?wH$w#Mh{fXR(OqI3d zWuoP8rvGXgRkTAQ|A)v0etge(e6O8aDi@2smczOGod~|totKV3T(w!a%jNQ&y}$P>%9+)?rmaS;N|5G1Ou)l zQy?1A)TR1`3GcuE&&AmZ6A;*ZJGI{A`jwrT(y+$;U}NPzOWcST`Z2%*@MiI{0yX|x z#tO#wzVAk#(f(FpIvfKA{C|~W`wWGf=yKJyX~th`PjzYGZ^ zxO3nqA;!z2LXBDu_INzseD*gp-+p}h0^l)rT8IShXH*O_n(CBRgQsjqv>K`GMBC{> zS>`5F-jJQ>%2zEk1UBbtsRp^Sv%%|ht}`#td}OTgPXsRQ-a8a%1eO*$0=-l0bLYsl zaarK|TkCX1`BG0Mzg?QVenFOw(p(qSzKlDQV=YZllJk<>Y;V3`ewit2$;(vBKlx{X zRq2eK9XVC#_vB92ri^RMh{y*~Yar5-RMM|X&HNWaVzhCkiw#^A*xpS}6_0)R%P>@= zml&&GEs9jTiDHog{e&`=A1Y^p|NFAxk4+`;Ao>563jIeh{iwmzbl?Bq$oTaZ}*g`HiUiaG`vGcuWhI=@%yGx_kZv?S=C23?=_IVF(GH z9-c}d;o4j{_p|FKMd%!i0M!3$WfZAqz WmhHwGw$2*12)8&t!tK9&cYvSkP2!0F diff --git a/bin/com/codeboy/common/Category.class b/bin/com/codeboy/common/Category.class deleted file mode 100644 index fda0c6a3bb7ff49979007ce4fc0e46c20e728134..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1015 zcmah{-*3`T6#gy+3al_h#~f^P>Qv|^ga>^Aml^C9G6vB)65>;-6}$9@DP;-&m9mE| z8W*4aqm1WvZ1hF!L+?5FobNl|x##@;^Zg3ID^x^87>c@US9SNJF>ohz+P3Rdo0@M7 zU2h^H%8)tL&a|qfIm4>rjBSSHR_CCrbPih`MS0ii95QUQ7m(B$qUziB8-^vNb8@`h zd)+=!REEtD|3M`hx@9`1zsDey$~~fKlFS5RDUb*WS=?cWH)bjMQhP2`^*z%W)?4LX zl5+1#h#{VU$ep|d5pizamyke`sM@AubjJ3;@ZM_!%V5a0U0t(!nrCu9xJ*I7GD+}1 znbidvT z^>uSajWLLUi0&tbS{OF#y}a;sc{?QuPf%uf5k@yHZ8WNfO5W1Vq`vvxITm*8!xr5!{eEt{BG28?I diff --git a/bin/com/codeboy/common/Status.class b/bin/com/codeboy/common/Status.class deleted file mode 100644 index c5f01afd7f810a15fce7faa700b45eb370ae8cbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 996 zcmaJ$S(8-T(%HQh>TryYeKv#wPKfkm{OMTuasSE z(YSc+k20ROu+f{*i=NNtoaemf{QdXy2EcpNMZ_42hUYX4@3T4drX(H5a~o=)2a~ag zI79Yazt9`D?v5HAcj7Q4kJ_hQt;106-HU88q`Ljv#7w7ucD$_}_0BpfL*>(IT+6U6 z*9s08glbJ=h_{Jb3JD1e>oRh9Kpa|<Q()BxAAZHBb&`})-IzD*gF=m;mnbJGZ#-N;n8E*gtL3@My^VQ55Q zi^*#%UY3timGKHShPP2{+t$b9W~AX=u_bxFdD^L@dK2F;KUn;^GV>#;^DLT3wMH%- zjZcxiNHLCVt)O+#Jlvc7AS`8DAR z*-PX@<54^`HWI%nB+QUk2k{v;)JtssAVdsB`e(y#aja3d66vKd!lQIsiyr&r=bS`k zr*ehz5}c$2q8ftaP#00*WQph#Y%SpLs5FNcX4o8j6qK7mi!(YF%GY?h`<)_lD)VaW jjzXID^LkN3p&Z^z$}{B}Z~lPYkBdPGYwln-lzaaHTgTO3 diff --git a/bin/com/codeboy/mvc/config/SwaggerConfig.class b/bin/com/codeboy/mvc/config/SwaggerConfig.class deleted file mode 100644 index 2e549938d30bd5818239c54fa868da3fa4e703f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1644 zcmd^Yx15Qbl;p_^<|T0+ZL`Ea42h zv41RjJ!xCxEI^TA^+=3FV<2>|vDZ10v13?#th91Z85U~w1BPOYd;*jiR!+6gtu?lU zC02O(PFtCo!AKr*+BH=J;gr!lwWc$WN%n|`<#u0km88ZxZftKmORdtqt`&(qHueLL zh1SOLj^sa`{`M7RW|{u6V$!>zoqXl_(z!ESaCef*u>4F4om0r~lD$;woj1GxMAf49 z8!ffVX4v_8B+~WGAs4CI)m>Ao^R6`scl3|1ou46v=F*im^L2YcqOyzzI1&1{!?KSv zHk~aAQNnTs7jThby%wF)w(mSJO;6)Wq_liJOghrG1p&rTjZ7>C2f`|!PZx`>uQG-Q z(L4vC$q<;y92k~r^=LX2THkm()J`RGSC3St$bZM9I-Wh*FGhaC%@VFLR+-}*{5L#M zL#JRdl&GP8_SB}E4E;IUG@Fz;cw-3n&Ctg3g&I?G2Iy_imWS!gX>JDCr2EcqAK)H+ z!;}Mt%Bu3uc)h{{)5EntPB*LeLZ#me|O z#3fWIW4MepQms!_SLpY=+tnPmHWB4CcZ|`d z1gk99e5(wmIvV4UQ}9Ga!b+`pVssE;oId4Vd2ona#)&qTYctwR6C>5=z=#+>YV)3l zLMd%|fc&?o|HDM;g;(!kYNu6R0O3}1!R;hLuiV2A8R5GkNvI}Ezyq-iv8ONUt4m#t zwyZTW$Sf`i+@B~bK5=wif5@duky_bAmBoB_h|0+Veq7N&N6m|Xb-JEeIT8U^EYI$-peS>7(NSu6Fp#eTCAy zy7w6>-;Xg>S{(-He~s442@0-2oiqkl;Tn0mPI8fvdcz6yId?hQPu$&H;I6U2T@G%M QO%85D!`YH_hjtF|3pKl^3IG5A diff --git a/bin/com/codeboy/mvc/model/dao/CommentDao.class b/bin/com/codeboy/mvc/model/dao/CommentDao.class deleted file mode 100644 index 26d5a0eaaf480c04175c6c88788b338619b54f5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 379 zcma)&!Ab)`5Jaovnl;fi0sRD#e_s-gMi1kB?QWxWDz{CX5PCB^uXJo{CY=9vT;zX{ z#4X9>O1{Z#)o>j*aD>y*KZ4_D3AQh#j=T+Kawq@Li7<(+KMQSb_|7`v9DH|h_H|H~ jK-iJ`fJ7?UMOSnxs)IezJ@jQk*x$Sd$Ye)2TssDzFa~EB diff --git a/bin/com/codeboy/mvc/model/dao/IncorrectNoteDao.class b/bin/com/codeboy/mvc/model/dao/IncorrectNoteDao.class deleted file mode 100644 index da97c4b7d147a368c48edec7d8a671db9f7dc557..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 348 zcmZ`#%Sr=55Ufs2*2D*bsK1bSaIQkslL#)03IXr4lO{}<-G}e&Q#h5v#?^GYbPJbt?Y`o!_$N{l zv$dW*sLiG3CW^m*IMPe zT&mY(#l{hOSy^-Ce(wmk@$4U%YhmNjyU1$JMc>LM@$86RxGF1`+F~i z#8dyN`AD_n_S1d*e3J6!6?6VVm3!g?3JQ5~bvoq{XUGk#X zIvWYkt@8?(K?1+z*LKQ5YMz_uN@@1lYks!qV&yrn+L#g2RaMp|c8w#f@7sR6$-1f@ t|Egyn8Zlf+*I4&edCeIAA2mCb=@SSK`VWBg#wYYuC#rfFD5Yl_{sLxNTG0Ri diff --git a/bin/com/codeboy/mvc/model/dao/QuizRoomDao.class b/bin/com/codeboy/mvc/model/dao/QuizRoomDao.class deleted file mode 100644 index b99a818ca4052769a7efa3785e17e5a458c6da6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 525 zcma)(-Acni5QWdywy{-Xf5bNsk_+8iA^sqUP>B?+c)v-PvSpKnWK+;b^TG%4p~Okr z8leik+TEGi`R2^|{CfWYaET)a4Th80Bs?}#8JSm}EMlI}UGu3h{IO7PPsSv-!Z>I$ z^yXqAxEAS*kE6MaErYAlTxND%$*|-3BZlK;_(3L-%$`l1KJ~(Xc(&#(zXkpaLqC_A zKsQ>~JqDg1R+AJ~X&$QF1`M5vnx(=PnPfQMD7e^y8eCDE6>pr%nm6=De*mvHquWqc z+Dev7dzSVWsOjC8n!6KIWU;(cnzZ!RbC3yVrRp{VZJ7)NTI5L!ZIs?P*sabEx|H9e XYy diff --git a/bin/com/codeboy/mvc/model/dao/ScoreDao.class b/bin/com/codeboy/mvc/model/dao/ScoreDao.class deleted file mode 100644 index 2d9d910b121141924686a3167f38c00a4d4c9c9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 380 zcma)&K}*9x6olv1*x1(E;!p6DTzqG#3W5lQKo3Fh+s#t8Y_gJU3jQ?@{s4cJ_`0YR zMDX_Zn_*^|_m9^%05_PY7!WSBuUY%bto;kuJI%G+jw|K4)V?+M%BM&O^R3z`cBWxgcL`sYf8Lt$L{zSZWzI;ow0&v3c_-H<>ylKp^0 dRyoE{4nm3(;Ul2~jO9JSY2?$rF3MR{W}m~7XP*E7 diff --git a/bin/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.class b/bin/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.class deleted file mode 100644 index caf04d0bfc5752611a86bb1ce0e231c36c16ae12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 372 zcmZ`#%T5A85Ud7a0Ut5pB>n(gm=6Fw851`fFd=%M9Xe#l>`pQ}OX9D2@B{oPV=rA)H2@+Nw}}r$#8V?8hq}!s0hPxI?47&b+k@pwu&=Ce`PnNj&)$d{Qt&0 zJ7X>WSv$zj9z|*-o;mWV?+Kl8noizj$(EAnq({PFZ^Z(HEPOp|&+YuXFQyW(mB)>cCMYr8{0{@9&_KP5rmSO7kB{jwK ze)jL9HgLCoNoi%B&AMcx?B#~u!e1~|wGx-Ly?C8S{ZHJH zK!Q6z3NhXds!$LSHxA<&&wMju&3yj;21qhf9{k(%>ZEqJWZ&g0CP zcx03k+6B-g&^u!b7UxV)KlwqaB6_^plIkv9nT7 z4+(58GoLXh2yEAo@F-Nt)6HZ_U_Zg7|DD;$ zvS@7PmWvnCm+OpbMnCX$BCz*%t{pP+NH1h5vBA*OqaqR350iQYp3j*mxs`>dm*?~9 z*b%gqtPB^uVN#E&0l`v-(5~(gY*xBc`SAzh?5^P1Mejq* zCa9w?&^zt-Kf(653VRLDRu$QR>u7gs6x@KDReY~HZ^3QUyV&^-YKk&Ixr?$7@Doi# BI2Zr` diff --git a/bin/com/codeboy/mvc/model/dto/IncorrectNote.class b/bin/com/codeboy/mvc/model/dto/IncorrectNote.class deleted file mode 100644 index 7718f2a8658b6ed4da8e03ca755ccc79e496ead5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1019 zcmd5*OK%e~5FRHXk8L1r`ruJO=0tm8FFjFODXIVkt%5{KC5~RNmAKfRmDh>X|HK^$ zB)IoSRm^UJN>v2q#=$e6Jx|SiKEL?#4FC>+x1h%0sYDw~%v6eJv7O7<5;k!bFdjOI z-YXeK7*q=y3|3FYT*OAWN&GfFB@2U|{?%)kF<@^Pw5_tK^5wOYdrXb8C2qdZPKQGV z^_|@l28|=C)q>lUy_ZLAI*1FJvK7-AjvD1|u@UYGaf zV|)2DpILm6(t)*^Pn!XIpEh4!> z);;oMq@%CU{m{Sj8CJhnG3z9om8A|Fgu4qb*o3Xhez%hM;6CXss`P;LHl2rb9?^LW F@B>rAD4_rV diff --git a/bin/com/codeboy/mvc/model/dto/Member.class b/bin/com/codeboy/mvc/model/dto/Member.class deleted file mode 100644 index 95a6fbbfa5f836b54975d0ec5dc01c12f7c20705..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1153 zcmd5*OK%e~5FUp-H-WTiS{~(LN)O*-+cT2=?efnhCu@=1ZbjVnCJHZYNhlGg;l%0i z6_+tL4X6@WIb?Gdrc6!4*YP1w9D%0v;oS)V@{&MBAm~LWypc0PO&=mLW7fXc2IEa7 zk|V_=Cs5;(iIhNK#Z=|lQ|8dwFYnuTX*d>=TgPOE8R`gJZV7BgzgCM_Y88%r5NT~J zoI5@#bJZUSCEODN=LUBV2vm3QT@6?#&^@W~nK9Zl;UXa)_LbpQr*l3jI+BT$IiVHJ zjE++-?E@OL#xqWZ%(QV-Xqqskw4*VnKQEqQq*})M=s#iY>7kk09j&Z0dE&G=qb}++ zWz-#KJZKHm^xrPL;Lh+Om^;}~N{d$_Nm_daGNXoJttf7{#m2$#Nk?k4VaAF07r g#GR4_*WkL3-|#!dx&St?qAj$yaBbtdjq47;503go@c;k- diff --git a/bin/com/codeboy/mvc/model/dto/MemberUpdateRequest.class b/bin/com/codeboy/mvc/model/dto/MemberUpdateRequest.class deleted file mode 100644 index 61a0d62b6dd47d1c9e43200ef36b7528534d6ecf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1037 zcmd5*OK;Oa5S~raJlsIq^g*G3mRmW1FPwNuQ3VLe1gU8&aa^xQ$+r7&*Xv0APu!6} zf;&G7F?Nb7lnUsL!#uq6%|kPvzyJ9B6#!lU??8jWBk4>mU52SUkIh`hhI}1o!Nu>; zr09?GOawf@vl5HYffj?c6EPRD7IqrHPft(=23@P<=~x(KFibAPli-z|K4Z{O8G{ux zLTLu==gO+^l0kFt;W2~OK6UKC4F-eD%vat!--Q8VACIiZ!s$6?oMz3H7C|}7bMI1( zrg+Mu-r)?nGP(1CE61g<)&-s-|CRU~LOYYX)BglD(t6~l#lEve@TCmSUojXDjtd^n zbBuapcRlj?gEi<9I_aIRg$7RK>LqR93DC4Bi z$HJ@X`{J<`W~yKiC)Xk&u-)1+ zLi8Xay-Lw1gk)r+FVO!my!i>%zSTJ!q}z3*37h2i7bw_*?K*y|);n;U>^60}Lw1+s LF3CNT`v5-yD_$>T diff --git a/bin/com/codeboy/mvc/model/dto/Problem.class b/bin/com/codeboy/mvc/model/dto/Problem.class deleted file mode 100644 index 5cea3fc7ea50ed06d0bb0231c971f4e0daa0482d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1146 zcmd5*OK%e~5FUp#k8L0&Y0IM&oVJK^VFmQWONzonMXOSgQi-G2u@aYEPvmui@}IaP zfdqGc6k>L>Bvh$*+&I|ZH=gnAc=nrb-#>i;fX8sF3HDw36D1vk>Tv4c?=fI688mYHsY;~PL#NTuVKBegbyl1H zLk49zKrPkX8M`-Q_h)R6K}ne8y|N4{QaIH|J7KUH{8}*a7>(b_-ITlZNE_{*FgUk+ z`Bacq$^oIK+4VNz?(hZ9nOtNt_)?hxUxRxI-?un+%m#ZAa0+U3j6KQ-8|Z z{i`53P_g)ZeI7L7at&7C3WK%XMPa4?yB=tx4n}dP?2#b#rV2zUqGMroYUhVVH_!=# z?NeepQ~e|U6n6@*c)22;n)*7PAz4>H83rONL#}z2R5|oG)piEYZ)f~MXmvgM;cs|DqP^WmB zUh3&Z+8bo;QC3FieTL@S#@a`?^fk+QmG)BRS%MAXwP_SwgU!r;J=<>pCtRnBT7+A) LwrTCqx(Vu=vbeF1vq16d z%Dg`$vR!B+te(iZjC1Lx@vHPitANn)?A*@~@FgpcjWgjX!qU$DV}$k|m+8VX!tgxt znfK&-u!8vEjq|#se6BOW4HPDq!H^S$r!?2Ld?cd&(M$_t3-Uo25=uHpL8MxoCH@kT zlTGQ}e-d>-V?QnT$d$oYDvW}mM-x6Nv5cFkLCw~>BX4=X>_ZL9~ z!vS<*6=7p1Ip60bc;lwK^}dIRar&ULsrE;bSBNl5NXh(IdQ`R59$UGwhk*7jMe*YZc4*XjBA24G~yT5k_$`Vg6qk}QM0+1EC$-Z z#n=|G84kncOqa@=qUI=U1CyM85JC&CK&L^-)9JCL&)P%wBHz(xh~AC{AK~g()>?3l n&rai6f)V4vA_~@Ez431}=O$d|dy^~Q;QJ=aEtV~o+WVP=)EM+7nowe*Vmt}WM23cN8YUjY z*M)w+k7!;h6D!w*I)jyCF%e-Z>?nK{A1mp}^=^)~n=oK67_>|kRW2Kjl2kzF&oQT% zUUZu0F=DEO-6q}xZMA>IV4=Tt#Gt-IH)%qLLFbhH#5r^=SY_-<9bfOYYZ^(2i zyhh72hjFS*exC>JgR$b;WavEC$fd9rJ&zUt892vC(Zu-nKVj|Rz>V@9w7GYM^yq$b zFYb{G?oTomv6u`=S%_X}VddP}efYYf)=zjS}-owlRxvfrIZ zTeVk|T00QbLI&LkrAUv2)8%^RtoyOf8Qh7^D_l}mFvP-1^;DNxd-J-!TZ)Up=6+$l zHfq;Sbgt>RK`E9>Qgm7`I@1tJyB3`-JGooYw73jz ztV0bhK!Z>Xnlsy)*){~^r;kMyT%!3Rt?p42BO82%eM)&7-gz6zUUH|WG`WUte>LE|P34)6nEyE3o< diff --git a/bin/com/codeboy/mvc/model/dto/UserIncorrectNote.class b/bin/com/codeboy/mvc/model/dto/UserIncorrectNote.class deleted file mode 100644 index 0db1604bdf205b67acee7fd68934917bb31d65e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1039 zcmd5*OK%e~5FRHX*=$o%(l)%o+=>wFg%bg!r~(wU3W&6oIC{NS;uSC+u7nNn}M=UZ zm77?J&ME1q=v4<=47QHNN<^8k^XN@-OdbZ?#h=JY%7DFQ5Ex|=%0k!867<$#k||T( z+fTLC{yBr@-u)v6t$nK7flUVevjQ)iLl;1wv5$w=sT{MFN;!4B)S2)aEnn6N^Cvv) z9xN2sW{J*oja&+A(ep&{UxB|NGBgQ(_)kzXxll&@r5Wy#3+_*rD(p^i?B@AC+T6QB zdUWUD$60o$Oo6yVAL)qT`Y> z6|tyh5Z7y=bQ`J4rPIrjazyudZ54#siPr~C&p}*|wKD7Bjo=;-?dcOXp#hhmO;!Us zr#h%KeIJ@%NaqH59}|+14!=O}{owK^*!ot*Y}47UJWbdkyH}%N7lxJpYIR!gQN Q=?3XrB)3WKklY3M3A+I>)Bpeg diff --git a/bin/com/codeboy/mvc/model/dto/UserProblem.class b/bin/com/codeboy/mvc/model/dto/UserProblem.class deleted file mode 100644 index df5b7b0208c5b79de657650ef79eee9dea9776bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1216 zcmd5*OK%e~5FUp#k8Mgq+J;9dxV)NjUfvX z2_(4lqY$&3B}o-f#EpYJpU0oaI?e&;5kO9BVT{`Pgq^v7ZLkIGSq6y zs2vZ4Q*MP}%k<*5RnD=uOtE*}9V1wai}3Y&EkrxRmniX&h`Ztn~)Yo9NxgTL@a`D>UBM vuY87U-&5{3&V_Vm1#Td&OjvLeXu7|X&bQz;+6HEL2kku^yEvLS_5gkXrN34G diff --git a/bin/com/codeboy/mvc/model/dto/UserProblemSet.class b/bin/com/codeboy/mvc/model/dto/UserProblemSet.class deleted file mode 100644 index 5b3cb6dd00e629cf3c30df7b6811b6b3e36ff7ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1003 zcmd5*OK%e~5FWQ7*=zzS=>t%Cm|NNdd*MU?DXIV!tqLM-C5~S2C~;ZaE3Y?F{}Xp4 zDwR7w3NgD2s-hwVZpa$Xc>H;0H1qlUkFS>i@B$unV2!~@S{+H7Vq(uDy^xV6JBw0p zqmu&NduNjj^%Q*vS`0SM#6m=wFtg}ga)#2At6YK|rVQ9y27yMMpsSAU=gKJmlEM0D z@03C7fHHKT&tPyB?Ui%Z1#pY8&nL!VVY3CMoNCKeCcLtS=S?NWGah!2=g5`Lt@B)2 zE`>4H^91?thf9de>coEfPf$}iM=kzP4EL4`?$2`!yGM57X2pRug?FX&)~&!#vh3d; zyg~1ARaBb!N>B(r*yuw5w;61Y;;VU1y;Ej3uI4?6mBFL3V#Bc@GBFs&R*LLYI8~j0 zIa_|N3I_Y}-x6}nAe`FLNqnuUsGG}teNq*}VE035ywZ4R7OGH`Zc>q@rW9oh;$|Qe ztCwOSoyse+QLy;h5D2psUvD+JgScsEZ8mKi!($-A(??sQbpzV9)u}ao5b9W$_K>_! z3B^c<7ts4Sy!izN-)iiT_I7=<4x4268x(B8c74B7?|0xX=^e^&kMu6deUb+x4*`Ax D+N~x_ diff --git a/bin/com/codeboy/mvc/model/dto/UserScore.class b/bin/com/codeboy/mvc/model/dto/UserScore.class deleted file mode 100644 index 484e95a1ab6b6a705208a3a0c9fd8f015af77d35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 981 zcmd5*-D?yv5TCTy``Dhndj0UDDk&n=7x%>{YlWkzoGcZ*w%}tnJKUviGD|jh(ErJI zK|$aBql&Y8twkzY-y}@tm*khpF!Rgzv(H}vU=L&q76d%hWMfSkrgR$HnT{>vJkA2e zM2v|K)GZp8`jpMiJ3F;uAZPBLahnWEJM!-^8kr@vKG@l!1!V3Y5JCBbA zH1;`a3vLMLU50t-J^42Dg!p*mJeHKtFq525VR97=Iazp0bF}3%8FdaPD2*-12Wd!Z zqP)2H3nM3+(ueK|=)%n|bf7O_V<)-n=O}pN#=BL&dx>#)Fs;;asJMj!`Uz>3A1iOF_4#Ha zOiU@@QF09t?h1%TH1!%^nJVDQPkBD6QV_89Zt8-uICL{p8h&I@Nu(AMzp<8FX#+=G zPp%f5x7*3Qq&1uuZVv16FkH^C)ZP@8N?{vV=KQ4=cq~D)MlEQw=fA*pig;e;)l+5( z_R$yUzVEMmg4J&|ca7&}eXe2I3}HLn;L)$y7)k8A$Fwaq%I82$^Jf UhJ3h^>>c|=YF~(OEg4~O0JO|az5oCK diff --git a/bin/com/codeboy/mvc/model/service/IncorrectNoteService.class b/bin/com/codeboy/mvc/model/service/IncorrectNoteService.class deleted file mode 100644 index eea54f05f9adda47609f4f9ddc26044b7c9de7fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 345 zcmb7=KT88a5XIkI?s9sGCfHfpX^Jd}oqrlZ5RRmXq~BWy-Eemco6CV8D^Hmtx8>gsA;i~1w!}1*0y;fbgpmag!ox5W$56vj|5%9Ah$J7R#n0NO&28- zE^=pdIoI9>e+c8|(=G{j`SE1;gly(k-tdbJ_b>m$9|v+=K{(|fAe922Xev(aJdlhw cI9W>&ArlQ_$b+6}f7d5c&%_bVMI#LU05@?}6aWAK diff --git a/bin/com/codeboy/mvc/model/service/MemberService.class b/bin/com/codeboy/mvc/model/service/MemberService.class deleted file mode 100644 index 0d73745679abe03ce5252befb76b8de6438d3707..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 367 zcmah_%SyvQ6g{`bMr(ZFSELBe!ewwPDlLLR_mi1RoRVbfWRl{qx$p!0C~=xvL=@cI z7x$iX?s@-seFJcb;}|2tnXvZ;gmV0NKGW$K5&i)poz5NoB1>BYKPuj_q ztO!whv*t>=rIwzzY!~V6zeo?m#XUcF-1=+~oZHSRzA_aPPJcXpz7{_wgx`X7Kooq~ Z#W)m%7<)tB$7IL{NWuo;FvJm#J^_jsb_ofTC7q(Hta$kzA_Ki_mEW9g9ZI{0`MNAlO zWFti>t9LOkHd@t$_RLhKej>EScWXlY%o!P4=yZ{wO&H{+(yu#PXup!2M;PT!$#N~d z3I1;w*B@p}nC6!-JrJ^`+j*s5Oh~@@k30>uxCOKE*WgNli8W;>&K^ka54if|L4=Go UticD@tle{;aP6@p^jRYePO-yHxBvhE diff --git a/bin/com/codeboy/mvc/model/service/QuizRoomService.class b/bin/com/codeboy/mvc/model/service/QuizRoomService.class deleted file mode 100644 index 11f4bb1a533675bb422b1020a120c821fa2484fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 639 zcmZuvO>Yx15Pfc&uO%dHNcje>dfHTN_lij9g%62n0l`A0a&sIjIP%(+>sZ9)!kvHjkRpJ(3q*Y9sX06f9N2DTWEg)LHHr*dL1(_$&og3dZ!NVil%rf*C2 z<(;)feuW#@Vc4DXB~LXsv-HhmE`?`kj)Yc5`BR4NWN^l?^OR&7Xfbp*+0UJ`u8C_5 z=O2ud3#*rM8dCumN^`HQi7%X;XjwdtqgH-tJpUZaaOWsihAQ&$!SEpVwz{IFm+>p< zKiTOsDKvMLLKLBi>uq$+|)fi8L8+8Vn7JUVv zMyAzJC)^-(xMHL4XrA|?uW0`yb_=_-h8&=ey^0CHp@$p9^((wj_$F>4@V9ZN+VA2X L#Tf2a84vyduB4_o diff --git a/bin/com/codeboy/mvc/model/service/QuizRoomServiceImpl.class b/bin/com/codeboy/mvc/model/service/QuizRoomServiceImpl.class deleted file mode 100644 index bf485f03e17e7fc4c4cac52df7ff4bb184865ddc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1135 zcmb7DU2hUW6g@+sz=BZG)@rLR^`r2h8>0_KYLmu~1VS_xZK7|(GQlCcGdRp*>K`-F zMBn{U#=DfS#HGfE-FxTmx#ymH@9eMN-+lmiiv2873=e!AdcN+7u0Hj`vG0ZC2i{1S zvGj%aCX!!{wGKOH=VmwzvPd&*4EUIP0atzRb$1|qo5ecAz5gO(D14gIKj)fZznz@k z<9e=xfDMM7<49Q{aG5(BkcNtRMH+Ytkvo#4C!ao zUlwJC@}h+o#%PnnMTX`(WyDAaW6^U-%}@ptR(EJLl?k7?PJT}A`aCY{c7;37vD)RX zJsk?iK?#?NDBv=~X05#_*0Dyaej^rBZc8OzMPXN%x19JHDsAoa;Dj3)pQpjJ{V1ug zhb!iD&aSBca$nfl7Ta=UsYb1SCMU8o@ZuQ3@*UY%+(w2(JpK!Cu%dL&E>_bxY~*l* zq597eGL(EHxD_*9w3b?{-ef2av{Z{|rq*i3b1Ko56w7ehq5_=?I;il(qR&7d#X zB0t8*{uOMKWw?rKgxVoLh1~?E>j_NdM5dc?m$at<8 diff --git a/bin/com/codeboy/mvc/model/service/ScoreService.class b/bin/com/codeboy/mvc/model/service/ScoreService.class deleted file mode 100644 index 384f9b43cb9b9d45c46f93c19be6b0807494254f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 321 zcma)%Jx;?w5Jtao>^PW&{M>*JBE%j5NP|RWk-|~>^)iBuY_GI&EO9I8JRd+_!(pPHBzO#l^VVvjU4^qU0$wqft zRl0dq%W}h}CG_uYW7`FxcXhoc#E-HeLl0*|BpjyCvM@ryJc7vcm1W;U^pRPXFuP22)%@yyRX;rQjo(3aJAF$@~+84;e(rB*Qc0 S!@1<}&?izyLWB#+2;*Pu(n~V{ diff --git a/bin/com/codeboy/mvc/model/service/UserProblemService.class b/bin/com/codeboy/mvc/model/service/UserProblemService.class deleted file mode 100644 index 3f98a1daaf35c86f06e1dd8a4275618651161aae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 339 zcmb7Au}%U(6r6Y5ae9If8frVGa1AX;V`6nt5|Dmx-N=&L+hjQ|@w2Q%T zsBGrV%*&fh-r@Ue58xjC6cOQ0IV+TV)rET(wo$?|FU3~-#waabn9RK^N^KXvR*IO= z-^fOaQdV!`x!7n`6WUW#nR-TOUEiz-@dM{%XyLqr1Z_euH&2 - echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 - return 1 - fi - fi - else - JAVACMD="$( - 'set' +e - 'unset' -f command 2>/dev/null - 'command' -v java - )" || : - JAVACCMD="$( - 'set' +e - 'unset' -f command 2>/dev/null - 'command' -v javac - )" || : - - if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then - echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 - return 1 - fi - fi -} - -# hash string like Java String::hashCode -hash_string() { - str="${1:-}" h=0 - while [ -n "$str" ]; do - char="${str%"${str#?}"}" - h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) - str="${str#?}" - done - printf %x\\n $h -} - -verbose() { :; } -[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } - -die() { - printf %s\\n "$1" >&2 - exit 1 -} - -trim() { - # MWRAPPER-139: - # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. - # Needed for removing poorly interpreted newline sequences when running in more - # exotic environments such as mingw bash on Windows. - printf "%s" "${1}" | tr -d '[:space:]' -} - -scriptDir="$(dirname "$0")" -scriptName="$(basename "$0")" - -# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties -while IFS="=" read -r key value; do - case "${key-}" in - distributionUrl) distributionUrl=$(trim "${value-}") ;; - distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; - esac -done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" -[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" - -case "${distributionUrl##*/}" in -maven-mvnd-*bin.*) - MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ - case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in - *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; - :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; - :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; - :Linux*x86_64*) distributionPlatform=linux-amd64 ;; - *) - echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 - distributionPlatform=linux-amd64 - ;; - esac - distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" - ;; -maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; -*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; -esac - -# apply MVNW_REPOURL and calculate MAVEN_HOME -# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ -[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" -distributionUrlName="${distributionUrl##*/}" -distributionUrlNameMain="${distributionUrlName%.*}" -distributionUrlNameMain="${distributionUrlNameMain%-bin}" -MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" -MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" - -exec_maven() { - unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : - exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" -} - -if [ -d "$MAVEN_HOME" ]; then - verbose "found existing MAVEN_HOME at $MAVEN_HOME" - exec_maven "$@" -fi - -case "${distributionUrl-}" in -*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; -*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; -esac - -# prepare tmp dir -if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then - clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } - trap clean HUP INT TERM EXIT -else - die "cannot create temp dir" -fi - -mkdir -p -- "${MAVEN_HOME%/*}" - -# Download and Install Apache Maven -verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." -verbose "Downloading from: $distributionUrl" -verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" - -# select .zip or .tar.gz -if ! command -v unzip >/dev/null; then - distributionUrl="${distributionUrl%.zip}.tar.gz" - distributionUrlName="${distributionUrl##*/}" -fi - -# verbose opt -__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' -[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v - -# normalize http auth -case "${MVNW_PASSWORD:+has-password}" in -'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; -has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; -esac - -if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then - verbose "Found wget ... using wget" - wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" -elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then - verbose "Found curl ... using curl" - curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" -elif set_java_home; then - verbose "Falling back to use Java to download" - javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" - targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" - cat >"$javaSource" <<-END - public class Downloader extends java.net.Authenticator - { - protected java.net.PasswordAuthentication getPasswordAuthentication() - { - return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); - } - public static void main( String[] args ) throws Exception - { - setDefault( new Downloader() ); - java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); - } - } - END - # For Cygwin/MinGW, switch paths to Windows format before running javac and java - verbose " - Compiling Downloader.java ..." - "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" - verbose " - Running Downloader.java ..." - "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" -fi - -# If specified, validate the SHA-256 sum of the Maven distribution zip file -if [ -n "${distributionSha256Sum-}" ]; then - distributionSha256Result=false - if [ "$MVN_CMD" = mvnd.sh ]; then - echo "Checksum validation is not supported for maven-mvnd." >&2 - echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 - exit 1 - elif command -v sha256sum >/dev/null; then - if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then - distributionSha256Result=true - fi - elif command -v shasum >/dev/null; then - if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then - distributionSha256Result=true - fi - else - echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 - echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 - exit 1 - fi - if [ $distributionSha256Result = false ]; then - echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 - echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 - exit 1 - fi -fi - -# unzip and move -if command -v unzip >/dev/null; then - unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" -else - tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" -fi - -# Find the actual extracted directory name (handles snapshots where filename != directory name) -actualDistributionDir="" - -# First try the expected directory name (for regular distributions) -if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then - if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then - actualDistributionDir="$distributionUrlNameMain" - fi -fi - -# If not found, search for any directory with the Maven executable (for snapshots) -if [ -z "$actualDistributionDir" ]; then - # enable globbing to iterate over items - set +f - for dir in "$TMP_DOWNLOAD_DIR"/*; do - if [ -d "$dir" ]; then - if [ -f "$dir/bin/$MVN_CMD" ]; then - actualDistributionDir="$(basename "$dir")" - break - fi - fi - done - set -f -fi - -if [ -z "$actualDistributionDir" ]; then - verbose "Contents of $TMP_DOWNLOAD_DIR:" - verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" - die "Could not find Maven distribution directory in extracted archive" -fi - -verbose "Found extracted Maven distribution directory: $actualDistributionDir" -printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" -mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" - -clean || : -exec_maven "$@" diff --git a/codeBoy_backend/mvnw.cmd b/codeBoy_backend/mvnw.cmd deleted file mode 100644 index 92450f9..0000000 --- a/codeBoy_backend/mvnw.cmd +++ /dev/null @@ -1,189 +0,0 @@ -<# : batch portion -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Apache Maven Wrapper startup batch script, version 3.3.4 -@REM -@REM Optional ENV vars -@REM MVNW_REPOURL - repo url base for downloading maven distribution -@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven -@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output -@REM ---------------------------------------------------------------------------- - -@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) -@SET __MVNW_CMD__= -@SET __MVNW_ERROR__= -@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% -@SET PSModulePath= -@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( - IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) -) -@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% -@SET __MVNW_PSMODULEP_SAVE= -@SET __MVNW_ARG0_NAME__= -@SET MVNW_USERNAME= -@SET MVNW_PASSWORD= -@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) -@echo Cannot start maven from wrapper >&2 && exit /b 1 -@GOTO :EOF -: end batch / begin powershell #> - -$ErrorActionPreference = "Stop" -if ($env:MVNW_VERBOSE -eq "true") { - $VerbosePreference = "Continue" -} - -# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties -$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl -if (!$distributionUrl) { - Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" -} - -switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { - "maven-mvnd-*" { - $USE_MVND = $true - $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" - $MVN_CMD = "mvnd.cmd" - break - } - default { - $USE_MVND = $false - $MVN_CMD = $script -replace '^mvnw','mvn' - break - } -} - -# apply MVNW_REPOURL and calculate MAVEN_HOME -# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ -if ($env:MVNW_REPOURL) { - $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } - $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" -} -$distributionUrlName = $distributionUrl -replace '^.*/','' -$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' - -$MAVEN_M2_PATH = "$HOME/.m2" -if ($env:MAVEN_USER_HOME) { - $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" -} - -if (-not (Test-Path -Path $MAVEN_M2_PATH)) { - New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null -} - -$MAVEN_WRAPPER_DISTS = $null -if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { - $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" -} else { - $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" -} - -$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" -$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' -$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" - -if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { - Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" - Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" - exit $? -} - -if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { - Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" -} - -# prepare tmp dir -$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile -$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" -$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null -trap { - if ($TMP_DOWNLOAD_DIR.Exists) { - try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } - catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } - } -} - -New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null - -# Download and Install Apache Maven -Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." -Write-Verbose "Downloading from: $distributionUrl" -Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" - -$webclient = New-Object System.Net.WebClient -if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { - $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) -} -[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null - -# If specified, validate the SHA-256 sum of the Maven distribution zip file -$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum -if ($distributionSha256Sum) { - if ($USE_MVND) { - Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." - } - Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash - if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { - Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." - } -} - -# unzip and move -Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null - -# Find the actual extracted directory name (handles snapshots where filename != directory name) -$actualDistributionDir = "" - -# First try the expected directory name (for regular distributions) -$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" -$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" -if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { - $actualDistributionDir = $distributionUrlNameMain -} - -# If not found, search for any directory with the Maven executable (for snapshots) -if (!$actualDistributionDir) { - Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { - $testPath = Join-Path $_.FullName "bin/$MVN_CMD" - if (Test-Path -Path $testPath -PathType Leaf) { - $actualDistributionDir = $_.Name - } - } -} - -if (!$actualDistributionDir) { - Write-Error "Could not find Maven distribution directory in extracted archive" -} - -Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" -Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null -try { - Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null -} catch { - if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { - Write-Error "fail to move MAVEN_HOME" - } -} finally { - try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } - catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } -} - -Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/codeBoy_backend/pom.xml b/codeBoy_backend/pom.xml deleted file mode 100644 index e62266d..0000000 --- a/codeBoy_backend/pom.xml +++ /dev/null @@ -1,113 +0,0 @@ - - - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 3.5.8 - - - com.codeboy - codeBoy_backend - 0.0.1-SNAPSHOT - codeBoy_backend - Demo project for Spring Boot - - - - - - - - - - - - - - - 17 - - - - - org.springframework.boot - spring-boot-starter-web - - - org.mybatis.spring.boot - mybatis-spring-boot-starter - 3.0.5 - - - - org.springframework.boot - spring-boot-devtools - runtime - true - - - com.mysql - mysql-connector-j - runtime - - - org.springframework.boot - spring-boot-starter-test - test - - - org.mybatis.spring.boot - mybatis-spring-boot-starter-test - 3.0.5 - test - - - - org.springdoc - springdoc-openapi-starter-webmvc-ui - 2.3.0 - - - org.springframework.boot - spring-boot-starter - - - org.projectlombok - lombok - 1.18.42 - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.projectlombok - lombok - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - - org.projectlombok - lombok - - - - - - - - diff --git a/codeBoy_backend/src/main/resources/application.properties b/codeBoy_backend/src/main/resources/application.properties deleted file mode 100644 index b8c6c8d..0000000 --- a/codeBoy_backend/src/main/resources/application.properties +++ /dev/null @@ -1,24 +0,0 @@ -spring.application.name=codeBoy_backend - - - - -#dataSource -# -# -# -# -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -spring.datasource.url=jdbc:mysql://localhost:3306/board_test?serverTimezone=UTC -spring.datasource.username=ssafy -spring.datasource.password=ssafy - -#mybatis -#mapper -mybatis.mapper-locations=classpath:mappers/*.xml - -#type as -mybatis.type-aliases-package=com.codeboy.mvc.model.dto -mybatis.configuration.map-underscore-to-camel-case=true - -debug=true \ No newline at end of file diff --git a/pom.xml b/pom.xml deleted file mode 100644 index e38678b..0000000 --- a/pom.xml +++ /dev/null @@ -1,19 +0,0 @@ - - 4.0.0 - Backend - Backend - 0.0.1-SNAPSHOT - - codeBoy_backend/src/main/java - codeBoy_backend/src/test/java - - - maven-compiler-plugin - 3.8.1 - - 17 - - - - - \ No newline at end of file diff --git a/target/classes/META-INF/MANIFEST.MF b/target/classes/META-INF/MANIFEST.MF deleted file mode 100644 index b55046a..0000000 --- a/target/classes/META-INF/MANIFEST.MF +++ /dev/null @@ -1,4 +0,0 @@ -Manifest-Version: 1.0 -Build-Jdk-Spec: 17 -Created-By: Maven Integration for Eclipse - diff --git a/target/classes/META-INF/maven/Backend/Backend/pom.properties b/target/classes/META-INF/maven/Backend/Backend/pom.properties deleted file mode 100644 index 4c142b9..0000000 --- a/target/classes/META-INF/maven/Backend/Backend/pom.properties +++ /dev/null @@ -1,7 +0,0 @@ -#Generated by Maven Integration for Eclipse -#Fri Nov 28 09:27:07 KST 2025 -m2e.projectLocation=C\:\\minseung\\Backend -m2e.projectName=Backend -groupId=Backend -artifactId=Backend -version=0.0.1-SNAPSHOT diff --git a/target/classes/META-INF/maven/Backend/Backend/pom.xml b/target/classes/META-INF/maven/Backend/Backend/pom.xml deleted file mode 100644 index e38678b..0000000 --- a/target/classes/META-INF/maven/Backend/Backend/pom.xml +++ /dev/null @@ -1,19 +0,0 @@ - - 4.0.0 - Backend - Backend - 0.0.1-SNAPSHOT - - codeBoy_backend/src/main/java - codeBoy_backend/src/test/java - - - maven-compiler-plugin - 3.8.1 - - 17 - - - - - \ No newline at end of file diff --git a/target/classes/com/codeboy/CodeBoyBackendApplication.class b/target/classes/com/codeboy/CodeBoyBackendApplication.class deleted file mode 100644 index 61bc0a93a30e3540a68e390e01681881d612696b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 723 zcma)4%TB{E5FD36ODM1Meh7&JqVzy+Tnb1OiBkj;MdiTB2__g4yK)>JpT!Bpfe+xL z5bJ={9*V?eH#=+3&W`i>_5K0i0P7W$7`7sv`jNgCp?>y{DYx}=n@9ITT_5#&iHx|F zT2)YHn7QK*+)ucQ{j=~+M3!M}Un*%28AcjAU52tF@Gye$8b&e3FdaxGPV+Pr=7NWb zV5kQ=;z^eq>FQswY;R@8upRtMOp6AkTq=ge##PW4)v-pZxV6*uFpIeg>I_Y7Vn6FS z{KoK9JZf|Ahgw^|Q-A|2)-aC+TEyf;95x1cj}x9{tznabVf2w!RyLcFDWz@kaKwK&RApfT z&#fl8g-r2lNt@gmklVs0$QAlyfD(Ptvr?>3Qv|^ga>^Aml^C9G6vB)65>;-6}$9@DP;-&m9mE| z8W*4aqm1WvZ1hF!L+?5FobNl|x##@;^Zg3ID^x^87>c@US9SNJF>ohz+P3Rdo0@M7 zU2h^H%8)tL&a|qfIm4>rjBSSHR_CCrbPih`MS0ii95QUQ7m(B$qUziB8-^vNb8@`h zd)+=!REEtD|3M`hx@9`1zsDey$~~fKlFS5RDUb*WS=?cWH)bjMQhP2`^*z%W)?4LX zl5+1#h#{VU$ep|d5pizamyke`sM@AubjJ3;@ZM_!%V5a0U0t(!nrCu9xJ*I7GD+}1 znbidvT z^>uSajWLLUi0&tbS{OF#y}a;sc{?QuPf%uf5k@yHZ8WNfO5W1Vq`vvxITm*8!xr5!{eEt{BG28?I diff --git a/target/classes/com/codeboy/common/Status.class b/target/classes/com/codeboy/common/Status.class deleted file mode 100644 index c5f01afd7f810a15fce7faa700b45eb370ae8cbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 996 zcmaJ$S(8-T(%HQh>TryYeKv#wPKfkm{OMTuasSE z(YSc+k20ROu+f{*i=NNtoaemf{QdXy2EcpNMZ_42hUYX4@3T4drX(H5a~o=)2a~ag zI79Yazt9`D?v5HAcj7Q4kJ_hQt;106-HU88q`Ljv#7w7ucD$_}_0BpfL*>(IT+6U6 z*9s08glbJ=h_{Jb3JD1e>oRh9Kpa|<Q()BxAAZHBb&`})-IzD*gF=m;mnbJGZ#-N;n8E*gtL3@My^VQ55Q zi^*#%UY3timGKHShPP2{+t$b9W~AX=u_bxFdD^L@dK2F;KUn;^GV>#;^DLT3wMH%- zjZcxiNHLCVt)O+#Jlvc7AS`8DAR z*-PX@<54^`HWI%nB+QUk2k{v;)JtssAVdsB`e(y#aja3d66vKd!lQIsiyr&r=bS`k zr*ehz5}c$2q8ftaP#00*WQph#Y%SpLs5FNcX4o8j6qK7mi!(YF%GY?h`<)_lD)VaW jjzXID^LkN3p&Z^z$}{B}Z~lPYkBdPGYwln-lzaaHTgTO3 diff --git a/target/classes/com/codeboy/mvc/config/SwaggerConfig.class b/target/classes/com/codeboy/mvc/config/SwaggerConfig.class deleted file mode 100644 index 995d405f3bf1ab2eabaf890b738bff96bf76e1d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1317 zcma)5T~8B16g^W4+m=~D@GAL$F zH)fyAllt&*T$tRhisgj~ZfZ8ql8lVa7pf=<2rlLgM`ZOSVGBw-YZ#`ZIl?q3>uB7x z(%jBj!bq=LT2|jMt>>}|j{d^oS{=$C>Y5Q%aE>ALzmz`s;Z@MXFmNI?W@dAyp&O3v zLpQuKB&gy7E;9J24mBUceE8%SHaMb9)WHXa%POwmDwR;niFsqyq^h4*LO~ENaZ#zS zPenfl=s(MAhDWC;YXmkSOu;pV{u3)z=kj3?UJt_5i;2YS+;XV&>1%m&J4CG@T_Y-P z;3h+>BOKXlQ{i}{WfPA4!Kam}o+j!+gdsM)HZilP+YYh+O;mbyP=3E#-q{S5wmz13 z-W>0L4;}BlEAJeH${)6m_rLslyIb0NP0q+Pr*NriOvSiV)xM(JDNE#J+j%fSGRGt1 zkueFmqheA*l!9*Az4VD6A7*^!3uYktkS8OaR03$Za1iV=xLz2q9G)jK!v=A>;`?HPJfq>E=<*5au4_e&}v(j diff --git a/target/classes/com/codeboy/mvc/controller/MemberController.class b/target/classes/com/codeboy/mvc/controller/MemberController.class deleted file mode 100644 index 172042d32bb536ff73a2a0393d8a0d2dc38ea7a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1177 zcmb7D-A+_75T33JyDSKZf`Wf#Ra~Oj3x8rfUjVjETwl`}eugkiHHt_w4@W5_|4K>sptau#tFvM2Rr5jX;!ccqfuS3gc)| zs5GWC4WXP|lEM_J)2#%NaDq%f80Gid5op z>ie7L2uom~q5~c+awEOIWz4!4(h``c9D=1X5@Kbj(uBaR(w@i|$%$CQ=`DK8<9jP4 zFkDTs%~&i-E3uqOrL=3&gw@=vXcID<_-2+2kHv~MFWHKyv$|9b#&>+#oVIS3CyDQx zKu42DDR!D;+vOE^qs(!i%?Yy$?)HJDv5K8qvwQ83Nr6VFM!*|LqBkZMjTU7apvC`bK}f`$#v| z-qVc_YwK^`wjzBPi~3txE_JPR2S&YfR axfTe;9OqG|J3ymQ#M=uNF2W@XV}AhPFHqP3 diff --git a/target/classes/com/codeboy/mvc/model/dao/CommentDao.class b/target/classes/com/codeboy/mvc/model/dao/CommentDao.class deleted file mode 100644 index 26d5a0eaaf480c04175c6c88788b338619b54f5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 379 zcma)&!Ab)`5Jaovnl;fi0sRD#e_s-gMi1kB?QWxWDz{CX5PCB^uXJo{CY=9vT;zX{ z#4X9>O1{Z#)o>j*aD>y*KZ4_D3AQh#j=T+Kawq@Li7<(+KMQSb_|7`v9DH|h_H|H~ jK-iJ`fJ7?UMOSnxs)IezJ@jQk*x$Sd$Ye)2TssDzFa~EB diff --git a/target/classes/com/codeboy/mvc/model/dao/IncorrectNoteDao.class b/target/classes/com/codeboy/mvc/model/dao/IncorrectNoteDao.class deleted file mode 100644 index da97c4b7d147a368c48edec7d8a671db9f7dc557..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 348 zcmZ`#%Sr=55Ufs2*2D*bsK1bSaIQkslL#)03IXr4lO{}<-G}e&Q#h5v#?^GYbPJbt?Y`o!_$N{l zv$dW*sLiG3CW^m*IMPe zT&mY(#l{hOSy^-Ce(wmk@$4U%YhmNjyU1$JMc>LM@$86RxGF1`+F~i z#8dyN`AD_n_S1d*e3J6!6?6VVm3!g?3JQ5~bvoq{XUGk#X zIvWYkt@8?(K?1+z*LKQ5YMz_uN@@1lYks!qV&yrn+L#g2RaMp|c8w#f@7sR6$-1f@ t|Egyn8Zlf+*I4&edCeIAA2mCb=@SSK`VWBg#wYYuC#rfFD5Yl_{sLxNTG0Ri diff --git a/target/classes/com/codeboy/mvc/model/dao/QuizRoomDao.class b/target/classes/com/codeboy/mvc/model/dao/QuizRoomDao.class deleted file mode 100644 index b99a818ca4052769a7efa3785e17e5a458c6da6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 525 zcma)(-Acni5QWdywy{-Xf5bNsk_+8iA^sqUP>B?+c)v-PvSpKnWK+;b^TG%4p~Okr z8leik+TEGi`R2^|{CfWYaET)a4Th80Bs?}#8JSm}EMlI}UGu3h{IO7PPsSv-!Z>I$ z^yXqAxEAS*kE6MaErYAlTxND%$*|-3BZlK;_(3L-%$`l1KJ~(Xc(&#(zXkpaLqC_A zKsQ>~JqDg1R+AJ~X&$QF1`M5vnx(=PnPfQMD7e^y8eCDE6>pr%nm6=De*mvHquWqc z+Dev7dzSVWsOjC8n!6KIWU;(cnzZ!RbC3yVrRp{VZJ7)NTI5L!ZIs?P*sabEx|H9e XYy diff --git a/target/classes/com/codeboy/mvc/model/dao/ScoreDao.class b/target/classes/com/codeboy/mvc/model/dao/ScoreDao.class deleted file mode 100644 index 2d9d910b121141924686a3167f38c00a4d4c9c9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 380 zcma)&K}*9x6olv1*x1(E;!p6DTzqG#3W5lQKo3Fh+s#t8Y_gJU3jQ?@{s4cJ_`0YR zMDX_Zn_*^|_m9^%05_PY7!WSBuUY%bto;kuJI%G+jw|K4)V?+M%BM&O^R3z`cBWxgcL`sYf8Lt$L{zSZWzI;ow0&v3c_-H<>ylKp^0 dRyoE{4nm3(;Ul2~jO9JSY2?$rF3MR{W}m~7XP*E7 diff --git a/target/classes/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.class b/target/classes/com/codeboy/mvc/model/dao/UserIncorrectNoteDao.class deleted file mode 100644 index caf04d0bfc5752611a86bb1ce0e231c36c16ae12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 372 zcmZ`#%T5A85Ud7a0Ut5pB>n(gm=6Fw851`fFd=%M9Xe#l>`pQ}OX9D2@B{oPV=rA)H2@+Nw}}r$#8V?8hq}!s0hPxI?47&b+k@pwu&=Ce`PnNj&)$d{Qt&0 zJ7X>WSv$zj9z|*-o;mWV?+Kl8noizj$(EAnq({PFZ^Z(HEPOp|&+YuXFQyW(mB)>cCMYr8{0{@9&_KP5rmSO7kB{jwK ze)jL9HgLCoNoi%B&AMcx?B#~u!e1~u^5>{rsfe- zXvb{q4eJ@Dg!W}95@;UqIcG7~6Sg-x5RoTP#mw}6XH0-RCs0vBjf73za%8l}D*~c(-`PF&Au=j|-=#vb!w)EmmFKTJeW-8KJ)e zM&hYV%hh{174M`xAh5AN(;lg`qvz5|Y|u@2nr$EJx5MS>V!_pLX@(fBg!!a0GoJ^V z>x%}%W6IwSrD5(ZpG<^h^SjJ&$1+ak{h1PD$yq;|3dONhZ7f`5Ws*`8|LW)a4?jM= zquYZ$=l~KOU+O6+pp?)mKzX4nP|f@RYMHKQaeRlkh%J}8?3hJvU6s3c54W))Tn<&>E-1rR();%Kt diff --git a/target/classes/com/codeboy/mvc/model/dto/IncorrectNote.class b/target/classes/com/codeboy/mvc/model/dto/IncorrectNote.class deleted file mode 100644 index f68c8d482436c78763adb678771489475a84fc3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1045 zcmc&z&2AGh5FRHXKbt_>v;|7}aktzK>1Qz!Al(U4JA=`=e@P$BA{qEI?36Q4*s#@wuy3DMN zosANyGhDu>jPef%6gM^p1WMbOs{&_{<%sx^bJkU%Nr-%IoJ?&pl`+LC$134oSwrW9 z>0KJs`Xfn|9$V*WVs&I+P{EC{o<@@X3jQBnUE6lUblaNLyNU4DolqC`mU8O%$1yNf}Wi?As?%p^pB0Zm6bwZ?b*b5rDexVRjM#qJDYF537Bgs zJl1JsT@H`;6R)e`tZO-(^#mBqYsDn??*lnHr01IF8m?b>R`AZ3w5jSRDumb1ND#C@_>msb8Zb1nypN{}Y z3=e_?65M$fcm>4lZcst31e`dGXT~%0c|897<@<+E0Pp~A)S*IvMnt zLOWqYZ`d=T2Ex{%N??AMk2y=Yj@kBLS45sbLlxo8Ap!D~Kt-a_3J>#o-bx+c!^D(3 zw{I-Q8(KztnkzwIS|~0P0)dmU&e9F;akE|4yH^S8OC_A=Dn*1E8a{Ibmcw7WMOzuo zdPNY^n%KDTVpw9;?n^EGLjqHswH*T0b-Y&{775H9_V~zJV;gXW5b;7=;Y>0X!+avC zOt_au)6|+lB9yyJgPHzFP^nU5Jxz=nm^~VCt&OJxL4OwikE|`zwXs__+IgEr-q>UM zqTWzW{Xr^%nQoH&Tfr0Iz4#Mq?=O-9Xv5MhoPu)%7CT4Dl0Vd3D7Dzia_aRt&OT?A ziFmTZt<3$&X4Q`*GGg^NMjXdqBu3CPnT^C_nWHsJTHnf9fQ)*cX^&Lf)MM!+!guo* zE#4l{7s4a6MYwi&bb`3u2+KJYW;qQsmnH}790Pwdl!m!|9>>D6@oi?fV+Eti^O+Ju z$yqNN;a@>0n{npkrkrQ=}j2Qaxx3;+NC diff --git a/target/classes/com/codeboy/mvc/model/dto/MemberUpdateRequest.class b/target/classes/com/codeboy/mvc/model/dto/MemberUpdateRequest.class deleted file mode 100644 index d3baf05d1689d9c1475da0b9c2845f1c53f14e67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1070 zcmc&zOK%e~5FRIK9-BZ)+CoctxSWav_y8wfQdAy7T2iS=BlYOr9VKpe*NfK)>Ww3R z0Eq*K{0ESbK!Q7eh5QD@>?Wv(MuMI=jA!imX2zcR{NvY`ZvgNJZd9Pa;I^+L;p+fB zeJrA}FCwx-5m+r=V&tLOPXcLi4_}QiwG}8aSU!|vDMA?!#IARUzGYC2m4DQc5i)4G zC+@B_DjqywP*4GbC5)sB8I&KYSlP!6irY8)3`#pxu>$89G*2R*8lz1WnvCIoY%tZ~ z7z0jsO;jkY(lJkr_Ck!(``oGZhR9WvXk&S(BTpZ3U&gVv+(Z5+_yit%~qPJXWcq z!tHF6@<=6w1?`HL6s3TQu3AJwB$ke2B`){ck*|{~-@q?` z#0RiL2m})B`4s3kAm%2Qv?!5)RTtwqW6vCq?c;AhKYam!d$68@83L=q1WcHgY?=WJ z`ho?Beb#b@J+Y?g%OC{_0&{!3&zaA4o9#CDq;Lc>-O>7XivW2{pcuznG89&IoiZ9H zy~Dzqvr4z`5J-uRQ9|Avqg!LNF-DsNl3a)T(h^7u?qu880f80oXv2sDqggdxM(*TY zrIou+V79#8AdslyaZ<2Apm5m818a>g8YvX8B(%;3$k+owgwjEZD4xQ}@XY7=|s56vPH|WZ2rsDhmSMW$W zC;!G;`-h|~l;CV0=3t4yVtG;#(L)tHrR7d9Xi8h>D7#2HMsUBut%~A!GT}NZB(U~} z3Z}{ywUDiuo)z+;isdif+|+VHHsC_^Hz{11BJfXa-UkMLrYzZ0vKf&&U2`>`y@f^YJU= zJI&)*#Ap*)3Ht13C_OJOet<{1) T+8Wwrv@2*ithtJIErjwfao*p7Bp>>1P?IX4pq>?tYtwAKCrgSoXELk86i zf~iA`LFX{>k#p!8FwdBJZk@_7ovMUW0~4J}uhH^}!zfiIyUT;-V63<{6Lg-ZXd-;c zV`(jV9w~m1{6C_$u;)hE2HMQKJof00>5F^hlKZ`h3Yxt%{kMcC%6oMZYX2{S0tlef zhB_=TSY8Vc7t!}l+tGTls7|P@+R9C&+(6Ro8FWL8Wjd5j7y7=j>c=``a6LTvT-F%` zeau~~9_s>c{@{*o6%8<0-N~)jMs3=u&NP+i6PsFf0Guwi7pbgDCZK<b~6~*k#&doP7H}mcHU!T7Mz*RVthYW+dhoSJ$ zS1zuKaNvoM>_GSy#r?j1x{Mg!Q=zL&9(0_pKUY9&Qm9Os4%E(M&C3BO#u!t zrXEB_#TX2f&*>j}I*?Xl#CrzaK!x#TUMjY_itDh4#_|9|7aws?MiE->D*gxjKcW_~ zVLI_VMzJ-0&!X9-FK&@bZdZG%RBQynzX5J5Yt`SfHun%zf(fXNLm8$ROxL%pt!a&p zI&;aQDvplSVm~2COVaEaR2}qW(3VCg_mMMeyEfjd)j~ATv8Hm3WWy;Js9Me0F>6XY-N{bTJpztLKPlR)o)-f0#xun%%%WgtJ&g^?~oiTw25Xg}k0?x))&LNU^%FEH`2 zI{68z-%{)}ow@W&77mh~#8VU;g2SZ8V1~{N9D!NVRjPWF^f8j-BqvBXNtrN7U#DU? F{Tn3dLdF09 diff --git a/target/classes/com/codeboy/mvc/model/dto/UserIncorrectNote.class b/target/classes/com/codeboy/mvc/model/dto/UserIncorrectNote.class deleted file mode 100644 index fa5024b4c9225b50213f530e3ca7311a534787a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1076 zcmc&zJ8u&~5T3P7{0t6u5(o)oLlwkh3#bSnS>Yk0lY_8hiE{65WpB9Kwf5FV>1b%+ z4^X6VK}n0SK!TpXV)GXeb7!MSI1;3yn4Ov3Z@yX0plVUgg`D7 zp^Gf&F258B+w*q>cyY*$7EZaAlyuN?w~rtTY0Jd!c->f8k0jK4%+{aIgG8H&0Z z$Vg(+THNPkA~0vwnX5Q5FFW&f#p|3itzKeIYlP<7EJ6DO`sS-AxEmBFCx##UOcV@HYP{I$?(01(0#d9Hf$-pw& or6~$lU=_VIoKH{}U=4KzGH?;~I?4vhC6vo3MU2@*p%HBT0_T834gdfE diff --git a/target/classes/com/codeboy/mvc/model/dto/UserProblem.class b/target/classes/com/codeboy/mvc/model/dto/UserProblem.class deleted file mode 100644 index 3a1e83210c86001368e52bac496f739eddbbb136..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1241 zcmc&!-A)rh6g~sBg;J!JA4NpR9|V**QMmFiAw>;l1I7Z0m(%G}v%ZVUGZ^ih#H=?Mu$K%f?cSa>jFr=E zudSiQ;AC^nJ8hbe7z`=tv1#2tgV~^;2jR#XQO!P6XhF5CR(SsyJvc_o$7qE?UYd9h z9fMMm1C6iRjv=CKo%r{Wt)Wl&<{xXL{Zj^m3yV7pa#cEf0WLBaJE8l`IqQaCnlaoq z4r3d3vB4>QTZb|^9nTINKjg*Xtrl_}wXO3!v{Bu@{snrEe@jYj|7%bYreLN7<8Xz+2xyB7IVI(V+QlTiR+IdCz%y%w&N5&*GbB9-vhXp=z+n^Yf_Vr zaNTrutf|mya<{1psLn)iy33SwJUG?MMEpUoV=3(Qh2V5nVCRhVOM$i`-jmHHI?-Jg zR>mULRsTM|(QjIkFA7J_D;PB}1-S_t&j}8y`+SVpq2a-Mg35qZP=O9mL z017aa`e9m4<|Em>l=;!jpU?bQ=F4y)jjyD6=(*ALP0%<=t1DE6kuQFRsW+8NAK>!W zG~@BS;se?fe^sg%+}^(4!i_p!hC!Tb3B>+@FtcnE7Hm?O{%wPK-;M40nlgy-&SL zw=bwv18p2lv^=wdeU#4Pfn2oW^aSI4Ed>!(n$BoSN zLu0}9r6q97|JzMkC*XDT(1hZt%%V1rFWQ}~7y>IVhpCfFY^Eb=C8ld<6V7)5vo-w_ zy~ePM{>hG_x$MvSmW#9QptyXPpm$36+rHGyzUFZ(3>)2Lnp>7{*epL&B9feS!oE-( zLscVTLn8;-q7qo09*n2sH`DRK^uzlfA19gccJlMxgg)+W!y4cr-~rCzcMgiVRLVIX z4i2P(uZPxqh$6_nFHqfWoc{#%Z#lMsZ!!NgX$zF{@1a8$}j=}BJYLVIu6MHE1 zG!>fcTx7wDeUGl6T8A~LFjzW}Qz>$3hGI84z%($ZYt#w4UdDjEVzA%~Fxfo@)yK-H z@RY&)=G_5<$~Ljq-~xm83C(lotgAztG2Ax}z0IeXamr_`av790eC%wJqxO$@)Yuy# zS9)w+;JMX_ealm6j14?N{@eL~pmuE64gIz?KDbF5tUDtw9xRtU9F8$+bo2b*9A07w z_&3)6IY1G#;9?6J&|$E;8J{$wADlA7t)fxwSQ*@z6m8v;RC@-U*rqZcNT-VZ@nI#5 zlxJ`!KF9QIF^Kwh;!=E}3c|%db9KK+fx-Igi3v($&rFq96r@}9wVVKou^gYOFfp#g zr|U?^^>|jT(wxA#LXeK>mmkw4qpg$DqN!7JX|hOS742F2P$xt^g78klItWlNSfqxlZ1QN_yy7< BAwmEE diff --git a/target/classes/com/codeboy/mvc/model/service/CommentService.class b/target/classes/com/codeboy/mvc/model/service/CommentService.class deleted file mode 100644 index d44b062071fd50526967d8db9af0e76ff4d363a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 327 zcmb7e2I3}HLn;L)$y7)k8A$Fwaq%I82$^Jf UhJ3h^>>c|=YF~(OEg4~O0JO|az5oCK diff --git a/target/classes/com/codeboy/mvc/model/service/IncorrectNoteService.class b/target/classes/com/codeboy/mvc/model/service/IncorrectNoteService.class deleted file mode 100644 index eea54f05f9adda47609f4f9ddc26044b7c9de7fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 345 zcmb7=KT88a5XIkI?s9sGCfHfpX^Jd}oqrlZ5RRmXq~BWy-Eemco6CV8D^Hmtx8>gsA;i~1w!}1*0y;fbgpmag!ox5W$56vj|5%9Ah$J7R#n0NO&28- zE^=pdIoI9>e+c8|(=G{j`SE1;gly(k-tdbJ_b>m$9|v+=K{(|fAe922Xev(aJdlhw cI9W>&ArlQ_$b+6}f7d5c&%_bVMI#LU05@?}6aWAK diff --git a/target/classes/com/codeboy/mvc/model/service/MemberService.class b/target/classes/com/codeboy/mvc/model/service/MemberService.class deleted file mode 100644 index 0d73745679abe03ce5252befb76b8de6438d3707..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 367 zcmah_%SyvQ6g{`bMr(ZFSELBe!ewwPDlLLR_mi1RoRVbfWRl{qx$p!0C~=xvL=@cI z7x$iX?s@-seFJcb;}|2tnXvZ;gmV0NKGW$K5&i)poz5NoB1>BYKPuj_q ztO!whv*t>=rIwzzY!~V6zeo?m#XUcF-1=+~oZHSRzA_aPPJcXpz7{_wgx`X7Kooq~ Z#W)m%7<)tB$7IL{NWuo;FvJm#J^_jsb_ofTC7q(Hta$kzA_Ki_mEW9g9ZI{0`MNAlO zWFti>t9LOkHd@t$_RLhKej>EScWXlY%o!P4=yZ{wO&H{+(yu#PXup!2M;PT!$#N~d z3I1;w*B@p}nC6!-JrJ^`+j*s5Oh~@@k30>uxCOKE*WgNli8W;>&K^ka54if|L4=Go UticD@tle{;aP6@p^jRYePO-yHxBvhE diff --git a/target/classes/com/codeboy/mvc/model/service/QuizRoomService.class b/target/classes/com/codeboy/mvc/model/service/QuizRoomService.class deleted file mode 100644 index 11f4bb1a533675bb422b1020a120c821fa2484fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 639 zcmZuvO>Yx15Pfc&uO%dHNcje>dfHTN_lij9g%62n0l`A0a&sIjIP%(+>sZ9)!kvHjkRpJ(3q*Y9sX06f9N2DTWEg)LHHr*dL1(_$&og3dZ!NVil%rf*C2 z<(;)feuW#@Vc4DXB~LXsv-HhmE`?`kj)Yc5`BR4NWN^l?^OR&7Xfbp*+0UJ`u8C_5 z=O2ud3#*rM8dCumN^`HQi7%X;XjwdtqgH-tJpUZaaOWsihAQ&$!SEpVwz{IFm+>p< zKiTOsDKvMLLKLBi>uq$+|)fi8L8+8Vn7JUVv zMyAzJC)^-(xMHL4XrA|?uW0`yb_=_-h8&=ey^0CHp@$p9^((wj_$F>4@V9ZN+VA2X L#Tf2a84vyduB4_o diff --git a/target/classes/com/codeboy/mvc/model/service/QuizRoomServiceImpl.class b/target/classes/com/codeboy/mvc/model/service/QuizRoomServiceImpl.class deleted file mode 100644 index fc89017dfc7b8529e6e2ed6add25570fec7766b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1035 zcmb7C+invv5FKxBZ5oo<R|BR22yVEQEwAwG>q#q(m!F8Hd)wkvuW>6Yol)V}2w8 zXY45#(*nMqICG+`>>+J_S83(;7-Z^=4uk9~w4w+ZsFYv{N(?H#((-K*b)|hTP?y1q zZvqi^gjIAOC$sLO!bYB5GR{A&#U3hs=_aQ8Dt4$*Z}_R(iBln`9Ksgcs;`AhEH<%y z4zPQPbkEJ4+}T5#a$u!!aw3Q`*ISJygM~=al+7Lk)?!c^7^P>RT)ovIgNl>qBU~B3 zjhv@K6F(rPZ4w*EH;U|9pK#25rzbQUYyi5BD~HR20xV!$#BZ9%Sj0$qd;{FC;EiKs zlzsRE%HQ$e!7}ay283V5ouE{<0;?DqT!ZU~TEnvkH&T*Em?ezIzNOh2!|EJ^H)U9d zD&k50ImQgtWWJuMtfrM~s6jd-Z93hATdCS@xHIN>iHIC7cDDUmN>NJ%@bT03X@C(0 bo$ewTd36tJW3uTe=Nj6&aFmU-z59OwxWnNv diff --git a/target/classes/com/codeboy/mvc/model/service/ScoreService.class b/target/classes/com/codeboy/mvc/model/service/ScoreService.class deleted file mode 100644 index 384f9b43cb9b9d45c46f93c19be6b0807494254f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 321 zcma)%Jx;?w5Jtao>^PW&{M>*JBE%j5NP|RWk-|~>^)iBuY_GI&EO9I8JRd+_!(pPHBzO#l^VVvjU4^qU0$wqft zRl0dq%W}h}CG_uYW7`FxcXhoc#E-HeLl0*|BpjyCvM@ryJc7vcm1W;U^pRPXFuP22)%@yyRX;rQjo(3aJAF$@~+84;e(rB*Qc0 S!@1<}&?izyLWB#+2;*Pu(n~V{ diff --git a/target/classes/com/codeboy/mvc/model/service/UserProblemService.class b/target/classes/com/codeboy/mvc/model/service/UserProblemService.class deleted file mode 100644 index 3f98a1daaf35c86f06e1dd8a4275618651161aae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 339 zcmb7Au}%U(6r6Y5ae9If8frVGa1AX;V`6nt5|Dmx-N=&L+hjQ|@w2Q%T zsBGrV%*&fh-r@Ue58xjC6cOQ0IV+TV)rET(wo$?|FU3~-#waabn9RK^N^KXvR*IO= z-^fOaQdV!`x!7n`6WUW#nR-TOUEiz-@dM{%XyLqr1Z_euHW8Qdp1}kXWD~ys>bRS|p|jBwBTMTvOa8c9b|kABzczfd}BB z5XS)_#DExlj?cxPkAJ_tzq|rC!)6@;Lr>a-OFL1KUGNL?1G^XqIag-VPt#aS;j}d) zmAkx-Dnn-`?gfv9neyvsrle!2oob`qIYVV{f6P$zlm;qTX<-R9hIXipx+;=LWg`*A zilG}?DdMrnw2!}%Rd=UzhQsjx6P+-$q%}@Gy3mRVo!+`BjMIr4>s%AMZ;W;23#hgo z+HA^a1r19!)lOwxq?-H35veh>MJCmy_7m>@Eya;nf#J9$=4qzQ^fnWTda&7?N7g#- z2uiw^v+-fsF`#^T7j{5m(I)@_EfR_1I_)@l<}1I)Ec1sjoAP`0LsCG*Z=?k From 0c3dc6a6f291acb81c599cf387c281f0fc43660c Mon Sep 17 00:00:00 2001 From: junhyung8795 Date: Tue, 2 Dec 2025 14:56:45 +0900 Subject: [PATCH 33/61] =?UTF-8?q?=EA=B9=83=EC=9D=B4=EA=B7=B8=EB=85=B8?= =?UTF-8?q?=EC=96=B4=20=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4f0d27e --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ +/.metadata/ + +.class \ No newline at end of file From 9a63e87d6a7ca6c4abb72ac76a94363e2c00ff1f Mon Sep 17 00:00:00 2001 From: junhyung8795 Date: Tue, 2 Dec 2025 15:00:30 +0900 Subject: [PATCH 34/61] fix: UserScoreServiceImpl --- .../com/codeboy/mvc/model/service/UserScoreServiceImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserScoreServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserScoreServiceImpl.java index eea3262..1733b62 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserScoreServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserScoreServiceImpl.java @@ -68,5 +68,4 @@ public int updateUser(UserScore userScore) { int result = userScoreDao.updateUserScore(userScore); return result; } -} - +} \ No newline at end of file From cdae9f0b2f4beb7c0576b0a22585290941403dc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=A4=80=ED=98=95?= <109512586+junhyung8795@users.noreply.github.com> Date: Tue, 2 Dec 2025 21:18:24 +0900 Subject: [PATCH 35/61] =?UTF-8?q?docs:=20=EB=B0=95=EC=A4=80=ED=98=95=20?= =?UTF-8?q?=EB=A6=AC=EB=93=9C=EB=AF=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5e97794..b492639 100644 --- a/README.md +++ b/README.md @@ -1 +1,72 @@ -# Backend \ No newline at end of file +# BangBang Codeboy (정보처리기사/SQLD 스피드 퀴즈 플랫폼) + +## 1. 프로젝트 개요 +- 정보처리기사와 sqld를 공부의 범위가 방대하여 공부하기 어려움. +- 각 자격증에서 배우는 내용을 쉽게 복습할 수 있는 시스템을 만든다. +- 반 친구들과 스피드 퀴즈 대결을 하며 재미있게 학습한다. +- 랭킹 기능을 제공하여 학습의 성취감을 얻는다. + +## 2. 핵심 기능 +- 정보처리기사와 sqld 관련 키워드를 활용한 4지선다 퀴즈 제공 +- 퀴즈방 생성 및 최대 20명과 실시간 대결 +- 오답노트 및 해설 제공 +- 유저 제작 문제 생성/수정/삭제 +- 리더보드 랭킹 +- 유저가 직접 문제를 제작 가능 +- 혹은 ChatGPT, Gemini로 문제를 자동으로 생성하고 해설을 제공 + +## 3. Tech Stack & 아키텍처 + image +
+ + - Spring, MySQL, MyBatis, Fast API -> 백엔드 API 개발과 데이터베이스, 외부 LLM 호출 서버 제작을 맡고 있음 + + +## 4. 시스템 설계 문서 +- [ERD] + 관통프로젝트 + +- [유즈케이스 다이어그램] + image + +- [기능 명세서 (구글 스프레드시트)](https://docs.google.com/spreadsheets/d/1pif1EVEQNDvyv444s-4GoqX6n816fivUlyM2uHmzNT8/edit?gid=0#gid=0) +- [WBS & 일정관리(Notion)](https://pointy-harpymimus-0cb.notion.site/2a76fbddf57780169009ed2301511ee1) +- [목업/화면 설계(Notion)](https://pointy-harpymimus-0cb.notion.site/2ab6fbddf57781839d13f9224dfa7a9c) + + +## 5. API 시나리오 테스트 +### 테스트 시나리오 +1. 모든 테이블의 데이터들만 삭제 +2. 회원가입 + 해당 유저의 점수 등록 +3. 로그인(전단계에서 회원가입한 유저의 id와 password를 이용) +4. 문제세트 전체조회 +5. 로그인한 회원이 만든 유저제작문제세트 조회 +6. 로그인한 회원이 유저제작문제 3개 추가 +7. 로그인한 회원이 유저제작문제 하나 수정 +8. 유저제작 문제의 댓글 조회 +9. 로그인한 회원이 댓글 3개 작성 +10. 로그인한 회원이 댓글 하나 수정 +11. 로그인한 회원이 댓글 삭제 +12. 로그인한 회원이 문제 세트 삭제 +13. 모든 회원들의 점수 조회 +14. 로그인한 회원 한명의 점수를 조회 +15. 로그인한 회원 한명의 점수를 수정 +16. 문제테이블(problem테이블) 에서 문제 전체 조회 +17. 문제테이블(problem테이블) 에서 문제 전체 조회 +18. 로그인한 회원의 오답노트에 문제 추가 후 로그인한 회원의 오답노트 안의 전체 문제 조회 +19. 로그인한 회원의 오답노트에 있는 문제 삭제(problem과 user_problem테이블에 있는 문제도 삭제되면 안됨) +20. 모든 퀴즈방 목록 조회 +21. 로그인한 회원이 퀴즈방을 생성하고 방장이 됨(isHost = 1) +22. 또 다른 mcp서버가 localhost:8082에서 가동되며 같은 DB 다른 회원을 가입하고 로그인 전체 퀴즈방들을 조회하여 조회된 퀴즈방에 들어가있는 회원들을 조회하고 isHost=0인 방장이 아닌 상태로 다른 방장이 만든 퀴즈방에 들어가기 +23. 방장인 회원이 퀴즈방을 삭제 + +### 테스트 방법 +1. html에 자바스크립트를 작성 후 axios 통신을 통해 Vite 프록시 서버에 요청을 보낸 후 응답을 console.log로 출력 +2. 테스트 결과를 testResultYYYYMMDDHH형식으로 다운로드 +image + + + +## 6. 향후 개선 계획 +- DeepseekOCR을 활용하여 개념요약 PDF -> 텍스트 -> 문제 제작 Flow 개발 / Fast API로 외부 LLM 호출하여 문제 생성 및 해설 기능 개발 +- API 테스트 파이프라인 제작 From 40f75745294f68f0139c9f8e440b9346be0fe6b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=A4=80=ED=98=95?= <109512586+junhyung8795@users.noreply.github.com> Date: Tue, 2 Dec 2025 21:28:58 +0900 Subject: [PATCH 36/61] =?UTF-8?q?docs:=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EA=B0=9C=EC=9A=94=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b492639..2fb41eb 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # BangBang Codeboy (정보처리기사/SQLD 스피드 퀴즈 플랫폼) ## 1. 프로젝트 개요 -- 정보처리기사와 sqld를 공부의 범위가 방대하여 공부하기 어려움. +- 정보처리기사와 sqld를 공부의 범위가 방대하여 공부에 어려움을 겪는 자격증 준비생 혹은 SSAFY생을 위해 제작 - 각 자격증에서 배우는 내용을 쉽게 복습할 수 있는 시스템을 만든다. - 반 친구들과 스피드 퀴즈 대결을 하며 재미있게 학습한다. - 랭킹 기능을 제공하여 학습의 성취감을 얻는다. From dd0843c3730ecc8021c2acbb267fbe15f7c8b684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=A4=80=ED=98=95?= <109512586+junhyung8795@users.noreply.github.com> Date: Tue, 2 Dec 2025 21:30:13 +0900 Subject: [PATCH 37/61] =?UTF-8?q?docs:=20=EB=A7=88=EC=B9=A8=ED=91=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 72 +++++++++++++++++++++++++++---------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 2fb41eb..bac0e4c 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,25 @@ # BangBang Codeboy (정보처리기사/SQLD 스피드 퀴즈 플랫폼) ## 1. 프로젝트 개요 -- 정보처리기사와 sqld를 공부의 범위가 방대하여 공부에 어려움을 겪는 자격증 준비생 혹은 SSAFY생을 위해 제작 +- 정보처리기사와 sqld를 공부의 범위가 방대하여 공부에 어려움을 겪는 자격증 준비생 혹은 SSAFY생을 위해 제작. - 각 자격증에서 배우는 내용을 쉽게 복습할 수 있는 시스템을 만든다. - 반 친구들과 스피드 퀴즈 대결을 하며 재미있게 학습한다. - 랭킹 기능을 제공하여 학습의 성취감을 얻는다. ## 2. 핵심 기능 -- 정보처리기사와 sqld 관련 키워드를 활용한 4지선다 퀴즈 제공 -- 퀴즈방 생성 및 최대 20명과 실시간 대결 -- 오답노트 및 해설 제공 -- 유저 제작 문제 생성/수정/삭제 -- 리더보드 랭킹 -- 유저가 직접 문제를 제작 가능 -- 혹은 ChatGPT, Gemini로 문제를 자동으로 생성하고 해설을 제공 +- 정보처리기사와 sqld 관련 키워드를 활용한 4지선다 퀴즈 제공. +- 퀴즈방 생성 및 최대 20명과 실시간 대결. +- 오답노트 및 해설 제공. +- 유저 제작 문제 생성/수정/삭제. +- 리더보드 랭킹. +- 유저가 직접 문제를 제작 가능. +- 혹은 ChatGPT, Gemini로 문제를 자동으로 생성하고 해설을 제공. ## 3. Tech Stack & 아키텍처 image
- - Spring, MySQL, MyBatis, Fast API -> 백엔드 API 개발과 데이터베이스, 외부 LLM 호출 서버 제작을 맡고 있음 + - Spring, MySQL, MyBatis, Fast API -> 백엔드 API 개발과 데이터베이스, 외부 LLM 호출 서버 제작을 맡고 있음. ## 4. 시스템 설계 문서 @@ -36,37 +36,37 @@ ## 5. API 시나리오 테스트 ### 테스트 시나리오 -1. 모든 테이블의 데이터들만 삭제 -2. 회원가입 + 해당 유저의 점수 등록 -3. 로그인(전단계에서 회원가입한 유저의 id와 password를 이용) -4. 문제세트 전체조회 -5. 로그인한 회원이 만든 유저제작문제세트 조회 -6. 로그인한 회원이 유저제작문제 3개 추가 -7. 로그인한 회원이 유저제작문제 하나 수정 -8. 유저제작 문제의 댓글 조회 -9. 로그인한 회원이 댓글 3개 작성 -10. 로그인한 회원이 댓글 하나 수정 -11. 로그인한 회원이 댓글 삭제 -12. 로그인한 회원이 문제 세트 삭제 -13. 모든 회원들의 점수 조회 -14. 로그인한 회원 한명의 점수를 조회 -15. 로그인한 회원 한명의 점수를 수정 -16. 문제테이블(problem테이블) 에서 문제 전체 조회 -17. 문제테이블(problem테이블) 에서 문제 전체 조회 -18. 로그인한 회원의 오답노트에 문제 추가 후 로그인한 회원의 오답노트 안의 전체 문제 조회 -19. 로그인한 회원의 오답노트에 있는 문제 삭제(problem과 user_problem테이블에 있는 문제도 삭제되면 안됨) -20. 모든 퀴즈방 목록 조회 -21. 로그인한 회원이 퀴즈방을 생성하고 방장이 됨(isHost = 1) -22. 또 다른 mcp서버가 localhost:8082에서 가동되며 같은 DB 다른 회원을 가입하고 로그인 전체 퀴즈방들을 조회하여 조회된 퀴즈방에 들어가있는 회원들을 조회하고 isHost=0인 방장이 아닌 상태로 다른 방장이 만든 퀴즈방에 들어가기 -23. 방장인 회원이 퀴즈방을 삭제 +1. 모든 테이블의 데이터들만 삭제. +2. 회원가입 + 해당 유저의 점수 등록. +3. 로그인(전단계에서 회원가입한 유저의 id와 password를 이용). +4. 문제세트 전체조회. +5. 로그인한 회원이 만든 유저제작문제세트 조회. +6. 로그인한 회원이 유저제작문제 3개 추가. +7. 로그인한 회원이 유저제작문제 하나 수정. +8. 유저제작 문제의 댓글 조회. +9. 로그인한 회원이 댓글 3개 작성. +10. 로그인한 회원이 댓글 하나 수정. +11. 로그인한 회원이 댓글 삭제. +12. 로그인한 회원이 문제 세트 삭제. +13. 모든 회원들의 점수 조회. +14. 로그인한 회원 한명의 점수를 조회. +15. 로그인한 회원 한명의 점수를 수정. +16. 문제테이블(problem테이블) 에서 문제 전체 조회. +17. 문제테이블(problem테이블) 에서 문제 전체 조회. +18. 로그인한 회원의 오답노트에 문제 추가 후 로그인한 회원의 오답노트 안의 전체 문제 조회. +19. 로그인한 회원의 오답노트에 있는 문제 삭제(problem과 user_problem테이블에 있는 문제도 삭제되면 안됨). +20. 모든 퀴즈방 목록 조회. +21. 로그인한 회원이 퀴즈방을 생성하고 방장이 됨(isHost = 1). +22. 또 다른 mcp서버가 localhost:8082에서 가동되며 같은 DB 다른 회원을 가입하고 로그인 전체 퀴즈방들을 조회하여 조회된 퀴즈방에 들어가있는 회원들을 조회하고 isHost=0인 방장이 아닌 상태로 다른 방장이 만든 퀴즈방에 들어가기. +23. 방장인 회원이 퀴즈방을 삭제. ### 테스트 방법 -1. html에 자바스크립트를 작성 후 axios 통신을 통해 Vite 프록시 서버에 요청을 보낸 후 응답을 console.log로 출력 -2. 테스트 결과를 testResultYYYYMMDDHH형식으로 다운로드 +1. html에 자바스크립트를 작성 후 axios 통신을 통해 Vite 프록시 서버에 요청을 보낸 후 응답을 console.log로 출력. +2. 테스트 결과를 testResultYYYYMMDDHH형식으로 다운로드. image ## 6. 향후 개선 계획 -- DeepseekOCR을 활용하여 개념요약 PDF -> 텍스트 -> 문제 제작 Flow 개발 / Fast API로 외부 LLM 호출하여 문제 생성 및 해설 기능 개발 -- API 테스트 파이프라인 제작 +- DeepseekOCR을 활용하여 개념요약 PDF -> 텍스트 -> 문제 제작 Flow 개발 / Fast API로 외부 LLM 호출하여 문제 생성 및 해설 기능 개발. +- API 테스트 파이프라인 제작. From fab477c0059465f13a5ee0a150e4dcb860da5183 Mon Sep 17 00:00:00 2001 From: junhyung8795 Date: Thu, 4 Dec 2025 17:55:27 +0900 Subject: [PATCH 38/61] =?UTF-8?q?fix:=20score,=20quiezRoom=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=20=ED=95=A9=EC=B9=9C=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B2=B0=EA=B3=BC=201.=20=EC=9D=B4=EC=A0=9C=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20=ED=9B=84=EC=97=90=20use?= =?UTF-8?q?r=5Fscore=ED=85=8C=EC=9D=B4=EB=B8=94=EC=97=90=EB=8F=84=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EC=9D=98=20member=5Fid=EA=B0=80=20=EC=98=AC?= =?UTF-8?q?=EB=9D=BC=EA=B0=90=202.=20=EB=B0=A9=EC=9E=A5=EC=9D=B4=20?= =?UTF-8?q?=ED=80=B4=EC=A6=88=EB=B0=A9=EC=9D=84=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=ED=95=98=EB=A9=B4=20=EA=B0=99=EC=9D=80=20=ED=80=B4=EC=A6=88?= =?UTF-8?q?=EB=B0=A9=EC=97=90=20=EC=9E=88=EB=8D=98=20=EC=82=AC=EB=9E=8C?= =?UTF-8?q?=EB=93=A4=EB=8F=84=20quiz=5Froom=5Fmember=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=EB=8F=BC=EC=84=9C=20=EB=82=98=EA=B0=90=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=EA=B0=80=20=EB=90=A8.=203.=20problem=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=ED=95=A0=EB=95=8C=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=EB=93=A4=20=EA=B0=9C=EC=88=98=EB=B3=B4?= =?UTF-8?q?=EB=8B=A4=20=EC=BF=BC=EB=A6=AC=EB=AC=B8=EC=97=90=20=EC=9E=88?= =?UTF-8?q?=EB=8A=94=20limit=EA=B0=80=20=ED=81=AC=EB=A9=B4=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=EA=B0=80=20=EB=82=98=EC=84=9C=20=EC=9D=BC=EC=8B=9C?= =?UTF-8?q?=EC=A0=81=EC=9C=BC=EB=A1=9C=20limit=EC=9D=84=20=EB=B0=9B?= =?UTF-8?q?=EB=8A=94=20=EC=BD=94=EB=93=9C=EB=93=A4=EC=9D=84=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=EC=B2=98=EB=A6=AC=ED=95=98=EA=B1=B0=EB=82=98=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=ED=95=A8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mvc/controller/CommentController.java | 2 +- .../codeboy/mvc/controller/MemberController.java | 1 + .../mvc/controller/ProblemController.java | 5 +++-- .../mvc/controller/UserProblemSetController.java | 5 +++-- .../com/codeboy/mvc/model/dao/ProblemDao.java | 3 ++- .../mvc/model/service/MemberServiceImpl.java | 9 ++++++++- .../mvc/model/service/ProblemService.java | 2 +- .../mvc/model/service/ProblemServiceImpl.java | 16 ++++++++-------- .../src/main/resources/mappers/ProblemMapper.xml | 1 - .../resources/mappers/UserProblemSetMapper.xml | 5 +---- .../main/resources/mappers/UserScoreMapper.xml | 2 +- 11 files changed, 29 insertions(+), 22 deletions(-) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java index 115df0d..45bc456 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java @@ -88,7 +88,7 @@ public ResponseEntity> updateComment( return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); } - + commentUpdateRequest.setMemberId(memberId); if (!memberId.equals(commentUpdateRequest.getMemberId())) { // 인가 실패 // 로그인 중인 회원이 자신이 작성한 댓글이 아닌 것을 수정하려할 때 diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java index 8e46fa6..65e265d 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java @@ -54,6 +54,7 @@ public ResponseEntity signUp(@RequestBody Member member) { if (result == 1) { // Location 헤더에 새로 생성된 리소스 URI 넣어줄 수도 있음 URI location = URI.create("/api/members/" + member.getMemberId()); + return ResponseEntity .status(HttpStatusCode.valueOf(201)) .location(location) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java index 05d5af5..cec4048 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java @@ -20,9 +20,10 @@ public class ProblemController { private ProblemServiceImpl problemService; @GetMapping - public ResponseEntity>> getProblems(@RequestParam int limit, @RequestParam Category category) { +// @RequestParam int limit, + public ResponseEntity>> getProblems( @RequestParam Category category) { try { - List problems = problemService.getProblems(limit, category); + List problems = problemService.getProblems(category); return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse<>(HttpStatus.OK, "문제가 성공적으로 반환되었습니다.", problems)); } catch (IllegalArgumentException e) { diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java index 6d454af..968b673 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java @@ -40,6 +40,7 @@ public ResponseEntity>> getAllUserProblemSets() @GetMapping("/me") public ResponseEntity> getMyUserProblemSet(HttpSession session) { Long memberId = (Long) session.getAttribute("memberId"); + System.out.println(memberId); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); @@ -64,7 +65,7 @@ public ResponseEntity> getMyUserProblemSet(HttpSessi // 마이페이지 - 문제세트 생성 @PostMapping - public ResponseEntity> createMyUserProblemSet(HttpSession session) { + public ResponseEntity> createMyUserProblemSet(HttpSession session) { Long memberId = (Long) session.getAttribute("memberId"); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) @@ -89,7 +90,7 @@ public ResponseEntity> createMyUserProblemSet(HttpSession sess } return ResponseEntity.status(HttpStatus.CREATED) - .body(ApiResponse.success(HttpStatus.CREATED, "유저 문제세트 생성 성공", null)); + .body(ApiResponse.success(HttpStatus.CREATED, "유저 문제세트 생성 성공", set)); } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ProblemDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ProblemDao.java index 8cbad50..fe372e7 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ProblemDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/ProblemDao.java @@ -10,5 +10,6 @@ @Mapper public interface ProblemDao { //문제 조회 - public List selectProblem(@Param("limit") int limit, @Param("category") Category category); +// @Param("limit") int limit + public List selectProblem( @Param("category") Category category); } \ No newline at end of file diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java index 8929d4b..a4ef431 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java @@ -1,7 +1,9 @@ package com.codeboy.mvc.model.service; import com.codeboy.mvc.model.dao.MemberDao; +import com.codeboy.mvc.model.dao.UserScoreDao; import com.codeboy.mvc.model.dto.Member; +import com.codeboy.mvc.model.dto.UserScore; import com.codeboy.mvc.model.dto.request.MemberUpdateRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -12,7 +14,10 @@ public class MemberServiceImpl implements MemberService { @Autowired MemberDao memberDao; - + + @Autowired + UserScoreDao userScoreDao; + //회원 정보 가져오기기 public Member getMemberById(Long memberId) { isMemberExist(memberId); @@ -73,6 +78,8 @@ public boolean checkEmailDuplicate(String email) { @Override public int signUp(Member member) { + UserScore userScore = new UserScore(member.getMemberId(), 0); + userScoreDao.insertScore(userScore); return memberDao.insertMember(member); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemService.java index bd2fd88..1986fc6 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemService.java @@ -9,6 +9,6 @@ @Service public interface ProblemService { - public List getProblems(int limit, Category category); + public List getProblems(Category category); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java index 38ead0c..ad0265c 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/ProblemServiceImpl.java @@ -14,19 +14,19 @@ public class ProblemServiceImpl implements ProblemService{ private ProblemDao problemDao; @Override - public List getProblems(int limit, Category category) { - if (limit <= 0) { - throw new IllegalArgumentException("limit의 수는 0이상이어야 합니다. limit: " + limit); - } + public List getProblems(Category category) { +// if (limit <= 0) { +// throw new IllegalArgumentException("limit의 수는 0이상이어야 합니다. limit: " + limit); +// } if (category == null) { throw new IllegalArgumentException("category의 값은 null이 될 수 없습니다. : category: "); } - List problems = problemDao.selectProblem(limit,category); + List problems = problemDao.selectProblem(category); //만약 요청 수보다 존재하는 문제 수가 적다면 - if (limit > problems.size()) { - throw new IllegalArgumentException("limit의 값은 문제 수보다 클 수 없습니다. problems: " + problems.size()); - } +// if (limit > problems.size()) { +// throw new IllegalArgumentException("limit의 값은 문제 수보다 클 수 없습니다. problems: " + problems.size()); +// } return problems; } diff --git a/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml b/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml index c48de03..ff28a26 100644 --- a/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/ProblemMapper.xml @@ -9,7 +9,6 @@ FROM problem WHERE category = #{category} ORDER BY RAND() - LIMIT #{limit}; \ No newline at end of file diff --git a/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml b/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml index 3498e1b..4bb7507 100644 --- a/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml @@ -18,10 +18,7 @@ - + INSERT INTO user_problem_set (member_id) VALUES (#{memberId}) diff --git a/codeBoy_backend/src/main/resources/mappers/UserScoreMapper.xml b/codeBoy_backend/src/main/resources/mappers/UserScoreMapper.xml index f40b22f..0997b3f 100644 --- a/codeBoy_backend/src/main/resources/mappers/UserScoreMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/UserScoreMapper.xml @@ -6,7 +6,7 @@ - INSERT INTO user_score(member_id, score) + INSERT INTO user_score (member_id, score) VALUES(#{memberId}, #{score}) From a7d599ac07c0ea5dc5eae5ff1a5300105b68b56b Mon Sep 17 00:00:00 2001 From: junhyung8795 Date: Fri, 5 Dec 2025 10:10:08 +0900 Subject: [PATCH 39/61] =?UTF-8?q?fix:=20maven=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../.mvn/wrapper/maven-wrapper.properties | 3 + codeBoy_backend/mvnw | 295 ++++++++++++++++++ codeBoy_backend/mvnw.cmd | 189 +++++++++++ codeBoy_backend/pom.xml | 113 +++++++ .../src/main/resources/application.properties | 24 ++ 5 files changed, 624 insertions(+) create mode 100644 codeBoy_backend/.mvn/wrapper/maven-wrapper.properties create mode 100755 codeBoy_backend/mvnw create mode 100644 codeBoy_backend/mvnw.cmd create mode 100644 codeBoy_backend/pom.xml create mode 100644 codeBoy_backend/src/main/resources/application.properties diff --git a/codeBoy_backend/.mvn/wrapper/maven-wrapper.properties b/codeBoy_backend/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..c0bcafe --- /dev/null +++ b/codeBoy_backend/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,3 @@ +wrapperVersion=3.3.4 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip diff --git a/codeBoy_backend/mvnw b/codeBoy_backend/mvnw new file mode 100755 index 0000000..bd8896b --- /dev/null +++ b/codeBoy_backend/mvnw @@ -0,0 +1,295 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.4 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/codeBoy_backend/mvnw.cmd b/codeBoy_backend/mvnw.cmd new file mode 100644 index 0000000..92450f9 --- /dev/null +++ b/codeBoy_backend/mvnw.cmd @@ -0,0 +1,189 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.4 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/codeBoy_backend/pom.xml b/codeBoy_backend/pom.xml new file mode 100644 index 0000000..e62266d --- /dev/null +++ b/codeBoy_backend/pom.xml @@ -0,0 +1,113 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.5.8 + + + com.codeboy + codeBoy_backend + 0.0.1-SNAPSHOT + codeBoy_backend + Demo project for Spring Boot + + + + + + + + + + + + + + + 17 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 3.0.5 + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + com.mysql + mysql-connector-j + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + org.mybatis.spring.boot + mybatis-spring-boot-starter-test + 3.0.5 + test + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.3.0 + + + org.springframework.boot + spring-boot-starter + + + org.projectlombok + lombok + 1.18.42 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/codeBoy_backend/src/main/resources/application.properties b/codeBoy_backend/src/main/resources/application.properties new file mode 100644 index 0000000..2ddba00 --- /dev/null +++ b/codeBoy_backend/src/main/resources/application.properties @@ -0,0 +1,24 @@ +spring.application.name=codeBoy_backend + + + + +#dataSource +# +# +# +# +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.datasource.url=jdbc:mysql://localhost:3306/board_test?serverTimezone=UTC +spring.datasource.username=root +spring.datasource.password=HardRain77 + +#mybatis +#mapper +mybatis.mapper-locations=classpath:mappers/*.xml + +#type as +mybatis.type-aliases-package=com.codeboy.mvc.model.dto +mybatis.configuration.map-underscore-to-camel-case=true + +debug=true \ No newline at end of file From 4ad935c82c62722a91bc0e08bd322a98a785deec Mon Sep 17 00:00:00 2001 From: junhyung8795 Date: Fri, 5 Dec 2025 15:41:41 +0900 Subject: [PATCH 40/61] =?UTF-8?q?fix:=20memberId=EB=A1=9C=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=EC=A0=9C=EC=9E=91=EB=AC=B8=EC=A0=9C=EC=84=B8=ED=8A=B8?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=ED=86=B5?= =?UTF-8?q?=EA=B3=BC,=20memberId=EB=A1=9C=20=ED=95=B4=EB=8B=B9=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=EC=9D=98=20=EC=A0=90=EC=88=98=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=ED=86=B5=EA=B3=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. memberId로 유저제작문제가 여러개 조회 가능하기에 UserProblemSetDao의 selectUserProblemSetByMemberId메서드의 반환값을 List<>로 변경하여 다중행을 받을 수 있게 변경 2. user_score테이블에 같은 memberId를 가지는 여러 행이 존재할 수 있어 user_score.memberId의 제약조건으로 UNIQUE를 추가 3. 유저제작 문제세트 추가-> 유저제작문제 추가 로 이어지는 로직 사이에 userProblemSetId가 브라우저로 전달되지 않는 문제가 있었음. -> UserProblemSetMapper.xml의 insertUserProblemSet 부분에 useGenerateKey와 keyProperty 속성을 추가하여 해결. --- .../codeboy/mvc/controller/UserProblemSetController.java | 8 +++++--- .../com/codeboy/mvc/model/dao/UserProblemSetDao.java | 4 ++-- .../codeboy/mvc/model/service/UserProblemSetService.java | 2 +- .../mvc/model/service/UserProblemSetServiceImpl.java | 9 ++++++--- .../src/main/resources/mappers/UserProblemSetMapper.xml | 5 ++++- .../src/main/resources/mappers/UserScoreMapper.xml | 2 +- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java index 968b673..2e9621b 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java @@ -38,7 +38,7 @@ public ResponseEntity>> getAllUserProblemSets() // 마이페이지 - 내가 만든 문제세트 조회 @GetMapping("/me") - public ResponseEntity> getMyUserProblemSet(HttpSession session) { + public ResponseEntity>> getMyUserProblemSet(HttpSession session) { Long memberId = (Long) session.getAttribute("memberId"); System.out.println(memberId); if (memberId == null) { @@ -47,7 +47,7 @@ public ResponseEntity> getMyUserProblemSet(HttpSessi } try { - UserProblemSet set = userProblemSetService.getUserProblemSetByMemberId(memberId); + List set = userProblemSetService.getUserProblemSetByMemberId(memberId); if (set == null) { return ResponseEntity.status(HttpStatus.NOT_FOUND) @@ -82,8 +82,10 @@ public ResponseEntity> createMyUserProblemSet(HttpSession session UserProblemSet set = new UserProblemSet(); set.setMemberId(memberId); System.out.println(set); - + int result = userProblemSetService.createUserProblemSet(set); + System.out.println(set); + if (result == 0) { return ResponseEntity.status(HttpStatus.BAD_REQUEST) .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "유저 문제세트 생성에 실패했습니다.")); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java index 3607529..1a0ffe6 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/UserProblemSetDao.java @@ -12,10 +12,10 @@ public interface UserProblemSetDao { //마이페이지에서 자신이 제작한 문제세트 조회 - UserProblemSet selectUserProblemSetByMemberId(long memberId); + List selectUserProblemSetByMemberId(long memberId); //문제 세트 등록 memberId = 문제 제작자만 넘겨주고 문제들은 problemDao에서 insertUserProblem으로 넣음 (마이페이지에서 생성) - int insertUserProblemSet(Long memberId); + int insertUserProblemSet(UserProblemSet userProblemSet); // 문제세트 삭제 (마이페이지에서 삭제) int deleteUserProblemSetById(Long userProblemSetId); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetService.java index e063488..ec15d55 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetService.java @@ -7,7 +7,7 @@ public interface UserProblemSetService { List getAllUserProblemSets(); - UserProblemSet getUserProblemSetByMemberId(Long memberId); + List getUserProblemSetByMemberId(Long memberId); int createUserProblemSet(UserProblemSet set); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetServiceImpl.java index 4d15576..4135072 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/UserProblemSetServiceImpl.java @@ -22,7 +22,10 @@ public List getAllUserProblemSets() { } @Override - public UserProblemSet getUserProblemSetByMemberId(Long memberId) { + public List getUserProblemSetByMemberId(Long memberId) { + if (memberId == null) { + throw new IllegalArgumentException("회원 ID가 필요합니다."); + } long memberIdl = memberId; return userProblemSetDao.selectUserProblemSetByMemberId(memberIdl); } @@ -32,8 +35,8 @@ public int createUserProblemSet(UserProblemSet set) { if (set.getMemberId() == null) { throw new IllegalArgumentException("회원 ID가 필요합니다."); } - long memberId = set.getMemberId(); - return userProblemSetDao.insertUserProblemSet(memberId); +// long memberId = set.getMemberId(); + return userProblemSetDao.insertUserProblemSet(set); } @Override diff --git a/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml b/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml index 4bb7507..f2572f7 100644 --- a/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/UserProblemSetMapper.xml @@ -18,7 +18,10 @@ - + INSERT INTO user_problem_set (member_id) VALUES (#{memberId}) diff --git a/codeBoy_backend/src/main/resources/mappers/UserScoreMapper.xml b/codeBoy_backend/src/main/resources/mappers/UserScoreMapper.xml index 0997b3f..3909667 100644 --- a/codeBoy_backend/src/main/resources/mappers/UserScoreMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/UserScoreMapper.xml @@ -15,7 +15,7 @@ From ff5cc47abd31dc1ffe02e790bc61550200bd14eb Mon Sep 17 00:00:00 2001 From: junhyung8795 Date: Mon, 8 Dec 2025 13:34:36 +0900 Subject: [PATCH 41/61] =?UTF-8?q?refact:=20=EB=AA=A8=EB=93=A0=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=EC=97=90=20Swagger=20@Tag=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/codeboy/mvc/controller/CommentController.java | 3 +++ .../com/codeboy/mvc/controller/IncorrectNoteController.java | 2 ++ .../java/com/codeboy/mvc/controller/ProblemController.java | 4 ++++ .../com/codeboy/mvc/controller/UserProblemController.java | 5 +++-- .../com/codeboy/mvc/controller/UserProblemSetController.java | 3 +++ .../java/com/codeboy/mvc/controller/UserScoreController.java | 4 ++++ 6 files changed, 19 insertions(+), 2 deletions(-) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java index 45bc456..c329651 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java @@ -21,8 +21,11 @@ import com.codeboy.mvc.model.dto.Comment; import com.codeboy.mvc.model.service.CommentService; +import io.swagger.v3.oas.annotations.tags.Tag; + @RestController @RequestMapping("/api/comments") +@Tag(name="Comment RESTful API", description = "Comment CRUD를 할 수 있는 REST API") public class CommentController { private final CommentService commentService; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java index be39c2d..405b907 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java @@ -5,6 +5,7 @@ import com.codeboy.mvc.model.dto.response.IncorrectNoteResponse; import com.codeboy.mvc.model.service.IncorrectNoteService; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpSession; import org.apache.ibatis.javassist.NotFoundException; @@ -16,6 +17,7 @@ @RestController @RequestMapping("api/incorrect-note") +@Tag(name="Incorrect-note RESTful API", description = "Incorrect-note CRUD를 할 수 있는 REST API") public class IncorrectNoteController { private final IncorrectNoteService incorrectNoteService; diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java index cec4048..4b1268c 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/ProblemController.java @@ -5,6 +5,9 @@ import com.codeboy.mvc.model.dto.response.ApiResponse; import com.codeboy.mvc.model.dto.Problem; import com.codeboy.mvc.model.service.ProblemServiceImpl; + +import io.swagger.v3.oas.annotations.tags.Tag; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -14,6 +17,7 @@ @RestController @RequestMapping("/api/problem") +@Tag(name="problem RESTful API", description = "problem을 조회할 수 있게하는 api") public class ProblemController { @Autowired diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java index 331eb24..5c3b423 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java @@ -3,9 +3,9 @@ import com.codeboy.mvc.model.dto.UserProblem; import com.codeboy.mvc.model.dto.response.ApiResponse; // 실제 패키지에 맞게 수정 import com.codeboy.mvc.model.service.UserProblemService; + +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpSession; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -14,6 +14,7 @@ @RestController @RequestMapping("/api/user-problems") +@Tag(name="User-problems RESTful API", description = "User-problems CRUD를 할 수 있는 REST API") public class UserProblemController { diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java index 2e9621b..c240bbd 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java @@ -3,6 +3,8 @@ import com.codeboy.mvc.model.dto.UserProblemSet; import com.codeboy.mvc.model.dto.response.ApiResponse; // 실제 패키지에 맞게 수정 import com.codeboy.mvc.model.service.UserProblemSetService; + +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,6 +16,7 @@ @RestController @RequestMapping("/api/user-problem-sets") +@Tag(name="User-problems-sets RESTful API", description = "User-problems-sets CRUD를 할 수 있는 REST API") public class UserProblemSetController { diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java index d2abb2b..3e2948f 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java @@ -8,12 +8,16 @@ import com.codeboy.mvc.model.dto.UserScore; import com.codeboy.mvc.model.service.UserScoreService; + +import io.swagger.v3.oas.annotations.tags.Tag; + import com.codeboy.mvc.model.dto.response.ApiResponse; import jakarta.servlet.http.HttpSession; @RestController @RequestMapping("api/scores") +@Tag(name="User-score RESTful API", description = "User-score를 CRUD를 할 수 있게하는 api") public class UserScoreController { private final UserScoreService userScoreService; From 0854b011bb03fa3f2590d6a4aeb676438697dbca Mon Sep 17 00:00:00 2001 From: mingeung Date: Mon, 8 Dec 2025 15:02:12 +0900 Subject: [PATCH 42/61] =?UTF-8?q?feat=20:=20JWT=20Spring=20Security=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codeBoy_backend/pom.xml | 23 ++++++ .../codeboy/mvc/config/SecurityConfig.java | 72 ++++++++++++++++ .../mvc/controller/AdminController.java | 13 +++ .../mvc/controller/JoinController.java | 22 +++++ .../mvc/controller/MainController.java | 13 +++ .../java/com/codeboy/mvc/jwt/JWTFilter.java | 69 ++++++++++++++++ .../java/com/codeboy/mvc/jwt/JWTUtil.java | 68 +++++++++++++++ .../java/com/codeboy/mvc/jwt/LoginFilter.java | 82 +++++++++++++++++++ .../com/codeboy/mvc/model/dao/MemberDao.java | 5 ++ .../mvc/model/dto/CustomUserDetails.java | 57 +++++++++++++ .../com/codeboy/mvc/model/dto/Member.java | 6 +- .../mvc/model/dto/request/JoinRequest.java | 15 ++++ .../service/CustomerUserDetailService.java | 30 +++++++ .../mvc/model/service/JoinService.java | 34 ++++++++ .../src/main/resources/application.properties | 7 +- .../main/resources/mappers/MemberMapper.xml | 23 ++++++ 16 files changed, 534 insertions(+), 5 deletions(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/controller/AdminController.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MainController.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/JWTFilter.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/JWTUtil.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CustomUserDetails.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/JoinRequest.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CustomerUserDetailService.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java diff --git a/codeBoy_backend/pom.xml b/codeBoy_backend/pom.xml index e62266d..c5cdbc0 100644 --- a/codeBoy_backend/pom.xml +++ b/codeBoy_backend/pom.xml @@ -78,6 +78,29 @@ lombok 1.18.42 + + + org.springframework.boot + spring-boot-starter-security + + + io.jsonwebtoken + jjwt-api + 0.12.3 + + + io.jsonwebtoken + jjwt-impl + 0.12.3 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.12.3 + runtime + + diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java new file mode 100644 index 0000000..84c1b9d --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java @@ -0,0 +1,72 @@ +package com.codeboy.mvc.config; + +import com.codeboy.mvc.jwt.LoginFilter; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +@Configuration +@EnableWebSecurity +@RequiredArgsConstructor +public class SecurityConfig { + + private final AuthenticationConfiguration authenticationConfiguration; + private final ObjectMapper objectMapper; // 필요 없으면 지워도 됨 + + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(); + } + + // 특정 Http 요청에 대한 웹 기반 보안 구성 + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + + // 기본 제공 로그인/HTTP Basic/CSRF 비활성화 + http + .formLogin(AbstractHttpConfigurer::disable) + .httpBasic(AbstractHttpConfigurer::disable) + .csrf(AbstractHttpConfigurer::disable); + + // 인가(접근 권한) 설정 + http + .authorizeHttpRequests(auth -> auth + .requestMatchers("/", "/login", "/join").permitAll() + .requestMatchers("/admin").hasRole("ADMIN") // "ADMIB" 오타 수정 + .anyRequest().authenticated() + ); + + // 세션 사용하지 않는(JWT 등) 방식으로 설정 + http + .sessionManagement(session -> + session.sessionCreationPolicy(SessionCreationPolicy.STATELESS) + ); + + // 커스텀 로그인 필터 추가 (UsernamePasswordAuthenticationFilter 위치에 대체) + AuthenticationManager authenticationManager = + authenticationConfiguration.getAuthenticationManager(); + + http.addFilterAt( + new LoginFilter(authenticationManager), + UsernamePasswordAuthenticationFilter.class + ); + + return http.build(); + } + + // AuthenticationManager를 Bean으로도 노출하고 싶으면 (선택사항) + @Bean + public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception { + return configuration.getAuthenticationManager(); + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/AdminController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/AdminController.java new file mode 100644 index 0000000..e35b5da --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/AdminController.java @@ -0,0 +1,13 @@ +package com.codeboy.mvc.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class AdminController { + + @GetMapping("/admin") + public String adminP() { + return "admin Controller"; + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java new file mode 100644 index 0000000..7a8e825 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java @@ -0,0 +1,22 @@ +package com.codeboy.mvc.controller; + +import com.codeboy.mvc.model.dto.request.JoinRequest; +import com.codeboy.mvc.model.service.JoinService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class JoinController { + private final JoinService joinService; + + @PostMapping("/join") + public String adminP(JoinRequest joinRequest) { + joinService.joinProcess(joinRequest); + return "ok"; + } + +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MainController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MainController.java new file mode 100644 index 0000000..ce0a235 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MainController.java @@ -0,0 +1,13 @@ +package com.codeboy.mvc.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class MainController { + + @GetMapping("/") + public String adminP() { + return "admin Controller"; + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/JWTFilter.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/JWTFilter.java new file mode 100644 index 0000000..dfd75c6 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/JWTFilter.java @@ -0,0 +1,69 @@ +package com.codeboy.mvc.jwt; + +import com.codeboy.mvc.model.service.CustomerUserDetailService; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +@RequiredArgsConstructor +public class JWTFilter extends OncePerRequestFilter { + + private final JWTUtil jwtUtil; + private final CustomerUserDetailService userDetailService; + + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain) + throws ServletException, IOException { + + // 1. 헤더에서 Authorization 꺼내기 + String authorization = request.getHeader("Authorization"); + + // 2. 토큰이 없거나 Bearer 형식이 아니면 → 그냥 다음 필터로 넘기고 끝 + if (authorization == null || !authorization.startsWith("Bearer ")) { + // System.out.println("JWTFilter: 토큰 없음"); + filterChain.doFilter(request, response); + return; + } + + // 3. "Bearer xxxxxx" 에서 실제 토큰 부분만 분리 + String token = authorization.substring(7); // "Bearer " 길이 = 7 + + // 4. 토큰 만료 여부 검사 + if (jwtUtil.isExpired(token)) { + // System.out.println("JWTFilter: 토큰 만료"); + filterChain.doFilter(request, response); + return; + } + + // 5. 토큰에서 username 추출 + String username = jwtUtil.getUsername(token); + // String role = jwtUtil.getRole(token); // 필요하면 role도 사용 가능 + + // 6. DB 또는 UserDetailsService를 통해 유저 정보 로드 + UserDetails userDetails = userDetailService.loadUserByUsername(username); + + // 7. Authentication 객체 생성 (credentials는 JWT 기반이라 null로 둬도 됨) + Authentication authToken = new UsernamePasswordAuthenticationToken( + userDetails, + null, + userDetails.getAuthorities() + ); + + // 8. SecurityContext에 등록 + SecurityContextHolder.getContext().setAuthentication(authToken); + + // 9. 다음 필터 진행 + filterChain.doFilter(request, response); + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/JWTUtil.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/JWTUtil.java new file mode 100644 index 0000000..26d5e70 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/JWTUtil.java @@ -0,0 +1,68 @@ +package com.codeboy.mvc.jwt; + +import io.jsonwebtoken.Jwts; +import jakarta.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.util.Date; + +@Component +public class JWTUtil { + + private final SecretKey secretKey; // JWT 서명용 시크릿 키 + + // application.yml / properties 에 정의된 값 주입 + // 예: spring.jwt.secret-key: my-jwt-secret-key... + public JWTUtil(@Value("${spring.jwt.secret-key}") String secret) { + this.secretKey = new SecretKeySpec( + secret.getBytes(StandardCharsets.UTF_8), + Jwts.SIG.HS256.key().build().getAlgorithm() + ); + } + + + public String getUsername(String token) { + return Jwts.parser() + .verifyWith(secretKey) + .build() + .parseSignedClaims(token) + .getPayload() + .get("username", String.class); + } + + public String getRole(String token) { + return Jwts.parser() + .verifyWith(secretKey) + .build() + .parseSignedClaims(token) + .getPayload() + .get("role", String.class); + } + + public boolean isExpired(String token) { + Date expiration = Jwts.parser() + .verifyWith(secretKey) + .build() + .parseSignedClaims(token) + .getPayload() + .getExpiration(); + + return expiration.before(new Date()); + } + + public String createJwt(String username, String role, Long expiredMs) { + long now = System.currentTimeMillis(); + + return Jwts.builder() + .claim("username", username) + .claim("role", role) + .issuedAt(new Date(now)) + .expiration(new Date(now + expiredMs)) + .signWith(secretKey) + .compact(); + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java new file mode 100644 index 0000000..0c5d299 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java @@ -0,0 +1,82 @@ +package com.codeboy.mvc.jwt; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +import java.io.IOException; + +@RequiredArgsConstructor +public class LoginFilter extends UsernamePasswordAuthenticationFilter { + + private final AuthenticationManager authenticationManager; + + /** + * 로그인 시도 시 호출되는 메서드 + */ + @Override + public Authentication attemptAuthentication(HttpServletRequest request, + HttpServletResponse response) + throws AuthenticationException { + + // 기본적으로 UsernamePasswordAuthenticationFilter가 제공하는 메서드 사용 + String username = obtainUsername(request); + String password = obtainPassword(request); + + // null일 수도 있으니 한 번 더 방어적으로 처리해도 됨 + if (username == null) { + username = request.getParameter("username"); + } + if (password == null) { + password = request.getParameter("password"); + } + + // 인증 객체 생성 (권한 컬렉션은 null 또는 빈 리스트로 전달) + UsernamePasswordAuthenticationToken authRequest = + new UsernamePasswordAuthenticationToken(username, password); + + // AuthenticationManager에게 실제 인증 위임 + return authenticationManager.authenticate(authRequest); + } + + /** + * 로그인 성공 시 호출되는 메서드 + * (JWT 발급 같은 작업을 여기서 하면 됨) + */ + @Override + protected void successfulAuthentication(HttpServletRequest request, + HttpServletResponse response, + FilterChain chain, + Authentication authResult) + throws IOException, ServletException { + + System.out.println("login success: " + authResult.getName()); + + // JWT 쓰고 싶으면 여기에서 토큰 만들어서 헤더에 담아주면 됨 + // response.addHeader("Authorization", "Bearer " + token); + + // 기본 흐름 계속 진행 + // (필요에 따라 chain.doFilter 호출 여부 선택) + chain.doFilter(request, response); + } + + /** + * 로그인 실패 시 호출되는 메서드 + */ + @Override + protected void unsuccessfulAuthentication(HttpServletRequest request, + HttpServletResponse response, + AuthenticationException failed) + throws IOException, ServletException { + + System.out.println("login fail: " + failed.getMessage()); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java index b1dc5e2..43e04b6 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java @@ -33,6 +33,11 @@ public interface MemberDao { // 로그인 - ID와 password로 회원 조회 Member selectMemberByIdAndPassword(@Param("id") String id, @Param("password") String password); + + //spring security + boolean existByUserId(String id); + + Member findByUserId(String id); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CustomUserDetails.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CustomUserDetails.java new file mode 100644 index 0000000..7e63a91 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CustomUserDetails.java @@ -0,0 +1,57 @@ +package com.codeboy.mvc.model.dto; + +import io.micrometer.observation.annotation.Observed; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.ArrayList; +import java.util.Collection; + +public class CustomUserDetails implements UserDetails { + private final Member member; + + public CustomUserDetails(Member member) { + this.member = member; + } + + @Override + public Collection getAuthorities() { + Collection collection = new ArrayList<>(); + + collection.add(new GrantedAuthority() { + @Override + public String getAuthority() { + return member.getRole(); + } + }); + return collection; + } + @Override + public String getPassword() { + return member.getPassword(); + } + + @Override + public String getUsername() { + return member.getId(); + } + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java index 25f245b..d87bfac 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Member.java @@ -24,8 +24,8 @@ public class Member { private Timestamp signupDate; private Boolean isActive; private Timestamp deletedDate; - - - + private String role; + + } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/JoinRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/JoinRequest.java new file mode 100644 index 0000000..e38606d --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/JoinRequest.java @@ -0,0 +1,15 @@ +package com.codeboy.mvc.model.dto.request; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class JoinRequest { + private String id; + private String password; + private String nickname; + private String email; +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CustomerUserDetailService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CustomerUserDetailService.java new file mode 100644 index 0000000..4fe9520 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CustomerUserDetailService.java @@ -0,0 +1,30 @@ +package com.codeboy.mvc.model.service; + +import com.codeboy.mvc.model.dao.MemberDao; +import com.codeboy.mvc.model.dto.CustomUserDetails; +import com.codeboy.mvc.model.dto.Member; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class CustomerUserDetailService implements UserDetailsService { + + // MemberDao는 Spring이 주입해야 함 (NEW 하면 안됨) + private final MemberDao memberDao; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + + Member userData = memberDao.findByUserId(username); + + if (userData == null) { + throw new UsernameNotFoundException("User not found: " + username); + } + + return new CustomUserDetails(userData); + } +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java new file mode 100644 index 0000000..748fec6 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java @@ -0,0 +1,34 @@ +package com.codeboy.mvc.model.service; + +import com.codeboy.mvc.model.dao.MemberDao; +import com.codeboy.mvc.model.dto.Member; +import com.codeboy.mvc.model.dto.request.JoinRequest; +import com.codeboy.mvc.model.dto.request.LoginRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class JoinService { + + private final MemberDao memberDao; + private final BCryptPasswordEncoder bCryptPasswordEncoder; + + public void joinProcess(JoinRequest request) { + + // 이미 같은 ID가 존재하면 가입 막기 + Member existing = memberDao.findByUserId(request.getId()); + if (existing != null) { + return; // 또는 예외 던지기 + } + + Member member = new Member(); + member.setId(request.getId()); + member.setPassword( + bCryptPasswordEncoder.encode(request.getPassword()) + ); + + memberDao.insertMember(member); + } +} diff --git a/codeBoy_backend/src/main/resources/application.properties b/codeBoy_backend/src/main/resources/application.properties index 2ddba00..3f5bc54 100644 --- a/codeBoy_backend/src/main/resources/application.properties +++ b/codeBoy_backend/src/main/resources/application.properties @@ -11,7 +11,7 @@ spring.application.name=codeBoy_backend spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/board_test?serverTimezone=UTC spring.datasource.username=root -spring.datasource.password=HardRain77 +spring.datasource.password=088alstmd! #mybatis #mapper @@ -21,4 +21,7 @@ mybatis.mapper-locations=classpath:mappers/*.xml mybatis.type-aliases-package=com.codeboy.mvc.model.dto mybatis.configuration.map-underscore-to-camel-case=true -debug=true \ No newline at end of file +debug=true + +#spring security +spring.jwt.secret-key=_1234567890abcdefghijkmnkopqrstu \ No newline at end of file diff --git a/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml index d253890..5d4a57a 100644 --- a/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml @@ -67,4 +67,27 @@ FROM member WHERE ID = #{id} AND password = #{password} AND is_active = 1 + + + + From 4ae6dc8472afa1337cfa6723e7f82a84ec752bab Mon Sep 17 00:00:00 2001 From: mingeung Date: Mon, 8 Dec 2025 15:03:15 +0900 Subject: [PATCH 43/61] =?UTF-8?q?feat=20:=20sql=20=EB=AC=B8=EC=84=9C=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codeBoy_backend/pom.xml | 5 + .../main/resources/db/migration/schema.sql | 286 ++++++++++++++++++ 2 files changed, 291 insertions(+) create mode 100644 codeBoy_backend/src/main/resources/db/migration/schema.sql diff --git a/codeBoy_backend/pom.xml b/codeBoy_backend/pom.xml index c5cdbc0..0ebbf2a 100644 --- a/codeBoy_backend/pom.xml +++ b/codeBoy_backend/pom.xml @@ -100,6 +100,11 @@ 0.12.3 runtime + + org.flywaydb + flyway-core + 10.17.2 + diff --git a/codeBoy_backend/src/main/resources/db/migration/schema.sql b/codeBoy_backend/src/main/resources/db/migration/schema.sql new file mode 100644 index 0000000..ba1bdbe --- /dev/null +++ b/codeBoy_backend/src/main/resources/db/migration/schema.sql @@ -0,0 +1,286 @@ +-- MySQL Script generated by MySQL Workbench +-- Mon Nov 24 16:21:44 2025 +-- Model: New Model Version: 1.0 +-- MySQL Workbench Forward Engineering +DROP DATABASE IF EXISTS board_test; +CREATE DATABASE board_test; +USE board_test; + +SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; +SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; +SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; + +-- ----------------------------------------------------- +-- Schema mydb +-- ----------------------------------------------------- +-- ----------------------------------------------------- +-- Schema board_test +-- ----------------------------------------------------- + +-- ----------------------------------------------------- +-- Schema board_test +-- ----------------------------------------------------- +CREATE SCHEMA IF NOT EXISTS `board_test` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci ; +USE board_test; + + +-- ----------------------------------------------------- +-- Table `board_test`.`member` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `board_test`.`member` ( + `member_id` BIGINT AUTO_INCREMENT, + `ID` VARCHAR(30) NOT NULL, + `password` CHAR(64) NOT NULL, + `nickname` VARCHAR(30) NOT NULL, + `email` VARCHAR(30) NOT NULL, + `signup_date` TIMESTAMP NOT NULL, + `is_active` TINYINT NOT NULL, + `deleted_date` TIMESTAMP NULL DEFAULT NULL, + `role` VARCHAR(20) NOT NULL DEFAULT 'USER', + PRIMARY KEY (`member_id`)) +ENGINE = InnoDB +DEFAULT CHARACTER SET = utf8mb4 +COLLATE = utf8mb4_0900_ai_ci; +-- SELECT DATABASE(); -- 지금 선택된 DB가 뭔지 +SHOW TABLES; -- 그 DB에 어떤 테이블이 있는지 +SHOW CREATE TABLE member; -- 진짜 member 테이블 정의 +-- SELECT * FROM member; -- 진짜 데이터 조회 + + + + + +-- SELECT * FROM member; -- 진짜 데이터 조회 + + +-- ----------------------------------------------------- +-- Table `board_test`.`user_problem_set` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `board_test`.`user_problem_set` ( + `user_problem_set_id` BIGINT NOT NULL AUTO_INCREMENT, + `member_id` BIGINT NOT NULL, + PRIMARY KEY (`user_problem_set_id`), + INDEX `FK_member_TO_user_problem_set_1` (`member_id` ASC) VISIBLE, + CONSTRAINT `FK_member_TO_user_problem_set_1` + FOREIGN KEY (`member_id`) + REFERENCES `board_test`.`member` (`member_id`)) +ENGINE = InnoDB +DEFAULT CHARACTER SET = utf8mb4 +COLLATE = utf8mb4_0900_ai_ci; + + +-- ----------------------------------------------------- +-- Table `board_test`.`comment` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `board_test`.`comment` ( + `comment_id` BIGINT NOT NULL AUTO_INCREMENT, + `content` VARCHAR(500) NOT NULL, + `comment_date` TIMESTAMP NOT NULL, + `member_id` BIGINT NOT NULL, + `user_problem_set_id` BIGINT NOT NULL, + PRIMARY KEY (`comment_id`), + INDEX `FK_member_TO_comment_1` (`member_id` ASC) VISIBLE, + INDEX `FK_user_problem_set_TO_comment_1` (`user_problem_set_id` ASC) VISIBLE, + CONSTRAINT `FK_member_TO_comment_1` + FOREIGN KEY (`member_id`) + REFERENCES `board_test`.`member` (`member_id`), + CONSTRAINT `FK_user_problem_set_TO_comment_1` + FOREIGN KEY (`user_problem_set_id`) + REFERENCES `board_test`.`user_problem_set` (`user_problem_set_id`)) +ENGINE = InnoDB +DEFAULT CHARACTER SET = utf8mb4 +COLLATE = utf8mb4_0900_ai_ci; + + +-- ----------------------------------------------------- +-- Table `board_test`.`problem` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `board_test`.`problem` ( + `problem_id` BIGINT NOT NULL AUTO_INCREMENT, + `problem_description` VARCHAR(300) NOT NULL, + `choice_1` VARCHAR(255) NOT NULL, + `choice_2` VARCHAR(255) NOT NULL, + `choice_3` VARCHAR(255) NOT NULL, + `choice_4` VARCHAR(255) NOT NULL, + `answer` VARCHAR(10) NOT NULL, + `category` VARCHAR(50) NOT NULL, + PRIMARY KEY (`problem_id`)) +ENGINE = InnoDB +DEFAULT CHARACTER SET = utf8mb4 +COLLATE = utf8mb4_0900_ai_ci; + +INSERT INTO problem (problem_description, choice_1, choice_2, choice_3, choice_4, answer, category) +VALUES +('문제1?', + 'SELECT', 'WHERE', 'ORDER BY', 'GROUP BY', 'WHERE', 'SQLD'); + +INSERT INTO problem (problem_description, choice_1, choice_2, choice_3, choice_4, answer, category) +VALUES +('문제2', + 'class', 'extends', 'new', 'this', 'new', 'SQLD'); + +INSERT INTO problem (problem_description, choice_1, choice_2, choice_3, choice_4, answer, category) +VALUES +('문제3', + 'GET', 'POST', 'PUT', 'DELETE', 'POST', 'INFOENGINEERING'); + + SELECT* FROM problem; + +-- ----------------------------------------------------- +-- Table `board_test`.`incorrect_note` +-- ----------------------------------------------------- +-- DROP TABLE IF EXISTS incorrect_note; + +CREATE TABLE IF NOT EXISTS `board_test`.`incorrect_note` ( + `incorrect_note_id` BIGINT NOT NULL AUTO_INCREMENT, + `member_id` BIGINT NOT NULL, + `problem_id` BIGINT, + `user_problem_id` BIGINT, + `is_user_problem` TINYINT NOT NULL, + + PRIMARY KEY (`incorrect_note_id`), + INDEX `FK_member_TO_incorrect_note_1` (`member_id` ASC) VISIBLE, + INDEX `FK_problem_TO_incorrect_note_1` (`problem_id` ASC) VISIBLE, + INDEX `FK_user_problem_TO_incorrect_note_1` (`user_problem_id` ASC) VISIBLE, + + CONSTRAINT `FK_member_TO_incorrect_note_1` + FOREIGN KEY (`member_id`) + REFERENCES `board_test`.`member` (`member_id`), + + CONSTRAINT `FK_problem_TO_incorrect_note_1` + FOREIGN KEY (`problem_id`) + REFERENCES `board_test`.`problem` (`problem_id`), + + CONSTRAINT `FK_user_problem_TO_incorrect_note_1` + FOREIGN KEY (`user_problem_id`) + REFERENCES `board_test`.`user_problem` (`user_problem_id`), + + CHECK ( + (is_user_problem= 0 AND problem_id IS NOT NULL AND user_problem_id IS NULL) OR + (is_user_problem= 1 AND user_problem_id IS NOT NULL AND problem_id IS NULL) + ) +) ENGINE = InnoDB + DEFAULT CHARACTER SET = utf8mb4 + COLLATE = utf8mb4_0900_ai_ci; + + + +-- 조회 + SELECT * FROM incorrect_note; + + + +-- ----------------------------------------------------- +-- Table `board_test`.`quiz_room` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `board_test`.`quiz_room` ( + `room_id` BIGINT NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`room_id`)) +ENGINE = InnoDB +DEFAULT CHARACTER SET = utf8mb4 +COLLATE = utf8mb4_0900_ai_ci; + +-- INSERT INTO +-- quiz_room() +-- VALUES(); +-- +-- SELECT * FROM quiz_room;-- + + +-- ----------------------------------------------------- +-- Table `board_test`.`quiz_room_member` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `board_test`.`quiz_room_member` ( + `quiz_room_member_id` BIGINT NOT NULL AUTO_INCREMENT, + `member_id` BIGINT NOT NULL, + `room_id` BIGINT NOT NULL, + `is_host` TINYINT(1) NULL DEFAULT NULL, + PRIMARY KEY (`quiz_room_member_id`), + INDEX `FK_member_TO_quiz_room_member_1` (`member_id` ASC) VISIBLE, + INDEX `FK_quiz_room_TO_quiz_room_member_1` (`room_id` ASC) VISIBLE, + UNIQUE INDEX `member_id_UNIQUE` (`member_id` ASC) VISIBLE, + CONSTRAINT `FK_member_TO_quiz_room_member_1` + FOREIGN KEY (`member_id`) + REFERENCES `board_test`.`member` (`member_id`), + CONSTRAINT `FK_quiz_room_TO_quiz_room_member_1` + FOREIGN KEY (`room_id`) + REFERENCES `board_test`.`quiz_room` (`room_id`)) +ENGINE = InnoDB +DEFAULT CHARACTER SET = utf8mb4 +COLLATE = utf8mb4_0900_ai_ci; + +-- 퀴즈룸이 삭제되면 퀴즈룸멤버테이블에서 퀴즈룸아이디를 가지고있는 row가 연쇄적으로 삭제 +ALTER TABLE quiz_room_member +DROP FOREIGN KEY FK_quiz_room_TO_quiz_room_member_1; + +ALTER TABLE quiz_room_member +ADD CONSTRAINT FK_quiz_room_TO_quiz_room_member_1 + FOREIGN KEY (room_id) + REFERENCES quiz_room (room_id) + ON DELETE CASCADE; + +-- ----------------------------------------------------- +-- Table `board_test`.`user_problem` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `board_test`.`user_problem` ( + `user_problem_id` BIGINT NOT NULL AUTO_INCREMENT, + `problem_description` VARCHAR(300) NOT NULL, + `category` VARCHAR(50) NOT NULL, + `choice_1` VARCHAR(255) NOT NULL, + `choice_2` VARCHAR(255) NOT NULL, + `choice_3` VARCHAR(255) NOT NULL, + `choice_4` VARCHAR(255) NOT NULL, + `answer` VARCHAR(10) NOT NULL, + `comment_count` INT NOT NULL DEFAULT 0, + `user_problem_set_id` BIGINT NOT NULL, + PRIMARY KEY (`user_problem_id`), + INDEX `FK_user_problem_set_TO_user_problem_1` (`user_problem_set_id` ASC) VISIBLE, + CONSTRAINT `FK_user_problem_set_TO_user_problem_1` + FOREIGN KEY (`user_problem_set_id`) + REFERENCES `board_test`.`user_problem_set` (`user_problem_set_id`)) +ENGINE = InnoDB +DEFAULT CHARACTER SET = utf8mb4 +COLLATE = utf8mb4_0900_ai_ci; + +INSERT INTO user_problem (problem_description, choice_1, choice_2, choice_3, choice_4, answer, category, user_problem_set_id) +VALUES +('유저 문제1', + 'SELECT', 'WHERE', 'ORDER BY', 'GROUP BY', 'WHERE', 'INFOENGINEERING', 1); + +INSERT INTO user_problem (problem_description, choice_1, choice_2, choice_3, choice_4, answer, category, user_problem_set_id) +VALUES +('유저 문제2', + 'class', 'extends', 'new', 'this', 'new', 'INFOENGINEERING', 1); + +INSERT INTO user_problem (problem_description, choice_1, choice_2, choice_3, choice_4, answer, category, user_problem_set_id) +VALUES +('유저 문제3', + 'GET', 'POST', 'PUT', 'DELETE', 'POST', 'SQLD', 1); + +-- SELECT* FROM problem; + -- SELECT * FROM user_problem; + + +-- ----------------------------------------------------- +-- Table `board_test`.`user_score` +-- ----------------------------------------------------- +-- user_score테이블고유의 아이디를 가지고있도록 변경. member_id가 이전에는 pk역할을했엇음 +-- 로직에 맞게 member_id를 member테이블에서 외래키로 가져오도록 변경 +CREATE TABLE IF NOT EXISTS user_score ( + user_score_id BIGINT NOT NULL AUTO_INCREMENT, -- 👉 점수 레코드 자체의 PK + member_id BIGINT NOT NULL, -- 👉 member 테이블 PK를 참조하는 FK + score INT NOT NULL, + PRIMARY KEY (user_score_id), + CONSTRAINT FK_member_TO_user_score_1 + FOREIGN KEY (member_id) + REFERENCES member (member_id) + ON DELETE CASCADE +); + +ALTER TABLE board_test.user_score +ADD CONSTRAINT user_score_unique_member_id UNIQUE (member_id); + + +SET SQL_MODE=@OLD_SQL_MODE; +SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; +SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; From 50553497ff6fd8b7919223ff84aa0b45f11eaf93 Mon Sep 17 00:00:00 2001 From: mingeung Date: Mon, 8 Dec 2025 16:13:38 +0900 Subject: [PATCH 44/61] =?UTF-8?q?feat=20:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EC=8B=9C=20=ED=9A=8C=EC=9B=90=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=EC=97=90=20=EA=B0=92=EC=9D=B4=20=EC=95=88=20=EB=93=A4?= =?UTF-8?q?=EC=96=B4=EA=B0=80=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=EB=94=94?= =?UTF-8?q?=EB=B2=84=EA=B9=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codeBoy_backend/pom.xml | 5 ++- .../codeboy/mvc/config/SecurityConfig.java | 4 ++ .../mvc/controller/JoinController.java | 3 +- .../com/codeboy/mvc/model/dao/MemberDao.java | 4 +- .../mvc/model/service/JoinService.java | 41 ++++++++++++++----- .../src/main/resources/application.properties | 7 +++- .../main/resources/mappers/MemberMapper.xml | 7 +++- 7 files changed, 54 insertions(+), 17 deletions(-) diff --git a/codeBoy_backend/pom.xml b/codeBoy_backend/pom.xml index 0ebbf2a..8fae8d8 100644 --- a/codeBoy_backend/pom.xml +++ b/codeBoy_backend/pom.xml @@ -103,7 +103,10 @@ org.flywaydb flyway-core - 10.17.2 + + + org.flywaydb + flyway-mysql diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java index 84c1b9d..325f7b4 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java @@ -1,5 +1,7 @@ package com.codeboy.mvc.config; +import com.codeboy.mvc.jwt.JWTFilter; +import com.codeboy.mvc.jwt.JWTUtil; import com.codeboy.mvc.jwt.LoginFilter; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; @@ -22,6 +24,8 @@ public class SecurityConfig { private final AuthenticationConfiguration authenticationConfiguration; private final ObjectMapper objectMapper; // 필요 없으면 지워도 됨 + private final JWTUtil jwtUtil; + @Bean public BCryptPasswordEncoder bCryptPasswordEncoder() { diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java index 7a8e825..35ed8ed 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java @@ -6,6 +6,7 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController @@ -14,7 +15,7 @@ public class JoinController { private final JoinService joinService; @PostMapping("/join") - public String adminP(JoinRequest joinRequest) { + public String adminP(@RequestBody JoinRequest joinRequest) { joinService.joinProcess(joinRequest); return "ok"; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java index 43e04b6..464a799 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/MemberDao.java @@ -38,6 +38,6 @@ public interface MemberDao { boolean existByUserId(String id); Member findByUserId(String id); - - + + String currentDatabase(); // 🔥 추가 } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java index 748fec6..8b8aee1 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java @@ -15,20 +15,41 @@ public class JoinService { private final MemberDao memberDao; private final BCryptPasswordEncoder bCryptPasswordEncoder; - public void joinProcess(JoinRequest request) { + public void joinProcess(JoinRequest req) { + // 1) 요청 값 로그 찍기 + System.out.println("JOIN REQ = id=" + req.getId() + + ", nickname=" + req.getNickname() + + ", email=" + req.getEmail()); - // 이미 같은 ID가 존재하면 가입 막기 - Member existing = memberDao.findByUserId(request.getId()); - if (existing != null) { - return; // 또는 예외 던지기 + // 2) 중복 아이디 체크 + Boolean exists = memberDao.existByUserId(req.getId()); + System.out.println("existByUserId = " + exists); + + if (Boolean.TRUE.equals(exists)) { + System.out.println("이미 존재하는 아이디라서 insert 안 함"); + return; } + // 3) Member 매핑 Member member = new Member(); - member.setId(request.getId()); - member.setPassword( - bCryptPasswordEncoder.encode(request.getPassword()) - ); + member.setId(req.getId()); + member.setPassword(bCryptPasswordEncoder.encode(req.getPassword())); + member.setNickname(req.getNickname()); + member.setEmail(req.getEmail()); + member.setIsActive(true); + member.setRole("USER"); + + // 4) insert 실행 + int rows = memberDao.insertMember(member); + System.out.println("insertMember rows = " + rows); + + + // 🔥 방금 넣은 회원 다시 조회 + Member saved = memberDao.findByUserId(member.getId()); + System.out.println("after insert findByUserId = " + saved); + + String dbName = memberDao.currentDatabase(); + System.out.println("==> APP is connected to DB: " + dbName); - memberDao.insertMember(member); } } diff --git a/codeBoy_backend/src/main/resources/application.properties b/codeBoy_backend/src/main/resources/application.properties index 3f5bc54..598f3d5 100644 --- a/codeBoy_backend/src/main/resources/application.properties +++ b/codeBoy_backend/src/main/resources/application.properties @@ -24,4 +24,9 @@ mybatis.configuration.map-underscore-to-camel-case=true debug=true #spring security -spring.jwt.secret-key=_1234567890abcdefghijkmnkopqrstu \ No newline at end of file +spring.jwt.secret-key=_1234567890abcdefghijkmnkopqrstu + +spring.flyway.enabled=false + +logging.level.org.mybatis=DEBUG +logging.level.org.springframework.jdbc.core=DEBUG diff --git a/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml index 5d4a57a..187a82a 100644 --- a/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml @@ -57,8 +57,8 @@ - INSERT INTO member (ID, password, nickname, email, is_active, signup_date) - VALUES (#{id}, #{password}, #{nickname}, #{email}, 1, NOW()); + INSERT INTO member (ID, password, nickname, email, is_active, signup_date, role) + VALUES (#{id}, #{password}, #{nickname}, #{email}, 1, NOW(), #{role}); @@ -89,5 +89,8 @@ WHERE id = #{id} LIMIT 1 + From 390d1899e53f9ed5e731b45ea8da9c83fdfe1af7 Mon Sep 17 00:00:00 2001 From: junhyung8795 Date: Mon, 8 Dec 2025 16:36:07 +0900 Subject: [PATCH 45/61] =?UTF-8?q?feat:=20AIProblem=EC=9A=A9=20Dto,=20?= =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=9C=EB=9F=AC,=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=20+=20Problem=EB=A5=98=EC=9D=98=20answer=ED=83=80?= =?UTF-8?q?=EC=9E=85=EC=9D=84=20String=EC=97=90=EC=84=9C=20Int=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codeBoy_backend/pom.xml | 21 +++++++++++++++++++ .../codeboy/mvc/model/dto/AIProblemDto.java | 15 +++++++++++++ .../com/codeboy/mvc/model/dto/Problem.java | 2 +- .../codeboy/mvc/model/dto/UserProblem.java | 2 +- .../model/dto/request/AIProblemRequest.java | 10 +++++++++ .../mvc/model/service/AIProblemService.java | 10 +++++++++ 6 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/AIProblemDto.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/AIProblemRequest.java create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/AIProblemService.java diff --git a/codeBoy_backend/pom.xml b/codeBoy_backend/pom.xml index e62266d..f261002 100644 --- a/codeBoy_backend/pom.xml +++ b/codeBoy_backend/pom.xml @@ -79,6 +79,27 @@ 1.18.42 + + + org.springframework.ai + spring-ai-starter-model-openai + + + + + org.springframework.ai + spring-ai-pdf-document-reader + + + + org.springframework.ai + spring-ai-core + + + + org.springframework.ai + spring-ai-vector-store + diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/AIProblemDto.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/AIProblemDto.java new file mode 100644 index 0000000..630a143 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/AIProblemDto.java @@ -0,0 +1,15 @@ +package com.codeboy.mvc.model.dto; + +import java.util.List; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class AIProblemDto { + + private String problemDescription; // 문제 본문 + private List choices; // 보기 4개 + private int answer; // 정답 인덱스 (0~3) +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Problem.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Problem.java index 195d199..f5487a2 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Problem.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Problem.java @@ -20,7 +20,7 @@ public class Problem { private String choice2; private String choice3; private String choice4; - private String answer; + private int answer; private Category category; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblem.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblem.java index 85aecc3..29ca54b 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblem.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblem.java @@ -21,7 +21,7 @@ public class UserProblem { private String choice2; private String choice3; private String choice4; - private String answer; + private int answer; private int commentCount; private Long userProblemSetId; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/AIProblemRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/AIProblemRequest.java new file mode 100644 index 0000000..9c69b63 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/AIProblemRequest.java @@ -0,0 +1,10 @@ +package com.codeboy.mvc.model.dto.request; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class AIProblemRequest { + private String category; // 정보처리기사 or SQLD +} diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/AIProblemService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/AIProblemService.java new file mode 100644 index 0000000..18fc965 --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/AIProblemService.java @@ -0,0 +1,10 @@ +package com.codeboy.mvc.model.service; + +import com.codeboy.ai.dto.AIProblemDto; +import com.codeboy.ai.dto.AIProblemRequest; + +import java.util.List; + +public interface AIProblemService { + List generateProblems(AIProblemRequest request); +} From 35ecfb28ad20cab6b493f0a12e7c9e8be7f7e3b2 Mon Sep 17 00:00:00 2001 From: mingeung Date: Mon, 8 Dec 2025 17:38:06 +0900 Subject: [PATCH 46/61] =?UTF-8?q?feat=20:=20dml,=20ddl=20=EC=8A=A4?= =?UTF-8?q?=ED=82=A4=EB=A7=88=EB=AC=B8=20=EB=B6=84=EB=A6=AC,=20=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=EA=B0=80=EC=9E=85=20=EC=8B=9C=20=EC=A4=91=EB=B3=B5?= =?UTF-8?q?=EB=90=9C=20=EC=95=84=EC=9D=B4=EB=94=94=EB=A9=B4=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mvc/controller/JoinController.java | 14 +++- .../mvc/model/service/JoinService.java | 27 +++----- .../migration/{schema.sql => DDL_schema.sql} | 69 +------------------ .../resources/db/migration/DML_schema.sql | 3 + .../main/resources/mappers/MemberMapper.xml | 2 +- 5 files changed, 27 insertions(+), 88 deletions(-) rename codeBoy_backend/src/main/resources/db/migration/{schema.sql => DDL_schema.sql} (81%) create mode 100644 codeBoy_backend/src/main/resources/db/migration/DML_schema.sql diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java index 35ed8ed..05af014 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java @@ -1,8 +1,11 @@ package com.codeboy.mvc.controller; import com.codeboy.mvc.model.dto.request.JoinRequest; +import com.codeboy.mvc.model.dto.response.ApiResponse; import com.codeboy.mvc.model.service.JoinService; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -15,9 +18,14 @@ public class JoinController { private final JoinService joinService; @PostMapping("/join") - public String adminP(@RequestBody JoinRequest joinRequest) { - joinService.joinProcess(joinRequest); - return "ok"; + public ResponseEntity> adminP(@RequestBody JoinRequest joinRequest) { + try { + Long memberId = joinService.joinProcess(joinRequest); + return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success( HttpStatus.CREATED, "회원가입에 성공했습니다.", memberId)); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } + } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java index 8b8aee1..8a744e6 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java @@ -15,19 +15,14 @@ public class JoinService { private final MemberDao memberDao; private final BCryptPasswordEncoder bCryptPasswordEncoder; - public void joinProcess(JoinRequest req) { - // 1) 요청 값 로그 찍기 - System.out.println("JOIN REQ = id=" + req.getId() - + ", nickname=" + req.getNickname() - + ", email=" + req.getEmail()); + public Long joinProcess(JoinRequest req) { + // 2) 중복 아이디 체크 Boolean exists = memberDao.existByUserId(req.getId()); - System.out.println("existByUserId = " + exists); if (Boolean.TRUE.equals(exists)) { - System.out.println("이미 존재하는 아이디라서 insert 안 함"); - return; + throw new IllegalArgumentException("이미 존재하는 아이디입니다."); } // 3) Member 매핑 @@ -39,17 +34,13 @@ public void joinProcess(JoinRequest req) { member.setIsActive(true); member.setRole("USER"); - // 4) insert 실행 + // 3) DB Insert int rows = memberDao.insertMember(member); - System.out.println("insertMember rows = " + rows); - - - // 🔥 방금 넣은 회원 다시 조회 - Member saved = memberDao.findByUserId(member.getId()); - System.out.println("after insert findByUserId = " + saved); - - String dbName = memberDao.currentDatabase(); - System.out.println("==> APP is connected to DB: " + dbName); + if (rows != 1) { + // 혹시 모를 예외 상황 방어 + throw new IllegalStateException("회원 가입에 실패했습니다. (insert rows = " + rows + ")"); + } + return member.getMemberId(); } } diff --git a/codeBoy_backend/src/main/resources/db/migration/schema.sql b/codeBoy_backend/src/main/resources/db/migration/DDL_schema.sql similarity index 81% rename from codeBoy_backend/src/main/resources/db/migration/schema.sql rename to codeBoy_backend/src/main/resources/db/migration/DDL_schema.sql index ba1bdbe..b7379e2 100644 --- a/codeBoy_backend/src/main/resources/db/migration/schema.sql +++ b/codeBoy_backend/src/main/resources/db/migration/DDL_schema.sql @@ -2,9 +2,9 @@ -- Mon Nov 24 16:21:44 2025 -- Model: New Model Version: 1.0 -- MySQL Workbench Forward Engineering -DROP DATABASE IF EXISTS board_test; -CREATE DATABASE board_test; -USE board_test; + -- DROP DATABASE IF EXISTS board_test; +-- CREATE DATABASE board_test; + USE board_test; SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; @@ -41,16 +41,6 @@ CREATE TABLE IF NOT EXISTS `board_test`.`member` ( ENGINE = InnoDB DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci; --- SELECT DATABASE(); -- 지금 선택된 DB가 뭔지 -SHOW TABLES; -- 그 DB에 어떤 테이블이 있는지 -SHOW CREATE TABLE member; -- 진짜 member 테이블 정의 --- SELECT * FROM member; -- 진짜 데이터 조회 - - - - - --- SELECT * FROM member; -- 진짜 데이터 조회 -- ----------------------------------------------------- @@ -109,23 +99,6 @@ ENGINE = InnoDB DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci; -INSERT INTO problem (problem_description, choice_1, choice_2, choice_3, choice_4, answer, category) -VALUES -('문제1?', - 'SELECT', 'WHERE', 'ORDER BY', 'GROUP BY', 'WHERE', 'SQLD'); - -INSERT INTO problem (problem_description, choice_1, choice_2, choice_3, choice_4, answer, category) -VALUES -('문제2', - 'class', 'extends', 'new', 'this', 'new', 'SQLD'); - -INSERT INTO problem (problem_description, choice_1, choice_2, choice_3, choice_4, answer, category) -VALUES -('문제3', - 'GET', 'POST', 'PUT', 'DELETE', 'POST', 'INFOENGINEERING'); - - SELECT* FROM problem; - -- ----------------------------------------------------- -- Table `board_test`.`incorrect_note` -- ----------------------------------------------------- @@ -164,12 +137,6 @@ CREATE TABLE IF NOT EXISTS `board_test`.`incorrect_note` ( COLLATE = utf8mb4_0900_ai_ci; - --- 조회 - SELECT * FROM incorrect_note; - - - -- ----------------------------------------------------- -- Table `board_test`.`quiz_room` -- ----------------------------------------------------- @@ -180,13 +147,6 @@ ENGINE = InnoDB DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci; --- INSERT INTO --- quiz_room() --- VALUES(); --- --- SELECT * FROM quiz_room;-- - - -- ----------------------------------------------------- -- Table `board_test`.`quiz_room_member` -- ----------------------------------------------------- @@ -242,28 +202,6 @@ ENGINE = InnoDB DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci; -INSERT INTO user_problem (problem_description, choice_1, choice_2, choice_3, choice_4, answer, category, user_problem_set_id) -VALUES -('유저 문제1', - 'SELECT', 'WHERE', 'ORDER BY', 'GROUP BY', 'WHERE', 'INFOENGINEERING', 1); - -INSERT INTO user_problem (problem_description, choice_1, choice_2, choice_3, choice_4, answer, category, user_problem_set_id) -VALUES -('유저 문제2', - 'class', 'extends', 'new', 'this', 'new', 'INFOENGINEERING', 1); - -INSERT INTO user_problem (problem_description, choice_1, choice_2, choice_3, choice_4, answer, category, user_problem_set_id) -VALUES -('유저 문제3', - 'GET', 'POST', 'PUT', 'DELETE', 'POST', 'SQLD', 1); - --- SELECT* FROM problem; - -- SELECT * FROM user_problem; - - --- ----------------------------------------------------- --- Table `board_test`.`user_score` --- ----------------------------------------------------- -- user_score테이블고유의 아이디를 가지고있도록 변경. member_id가 이전에는 pk역할을했엇음 -- 로직에 맞게 member_id를 member테이블에서 외래키로 가져오도록 변경 CREATE TABLE IF NOT EXISTS user_score ( @@ -280,7 +218,6 @@ CREATE TABLE IF NOT EXISTS user_score ( ALTER TABLE board_test.user_score ADD CONSTRAINT user_score_unique_member_id UNIQUE (member_id); - SET SQL_MODE=@OLD_SQL_MODE; SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; diff --git a/codeBoy_backend/src/main/resources/db/migration/DML_schema.sql b/codeBoy_backend/src/main/resources/db/migration/DML_schema.sql new file mode 100644 index 0000000..bfd1092 --- /dev/null +++ b/codeBoy_backend/src/main/resources/db/migration/DML_schema.sql @@ -0,0 +1,3 @@ + USE board_test; + + SELECT * FROM member; \ No newline at end of file diff --git a/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml index 187a82a..7c0343b 100644 --- a/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml @@ -56,7 +56,7 @@ WHERE member_id = #{memberId} - + INSERT INTO member (ID, password, nickname, email, is_active, signup_date, role) VALUES (#{id}, #{password}, #{nickname}, #{email}, 1, NOW(), #{role}); From 82ac1a4bdcf940eb27fcc380d2becec4acc810c4 Mon Sep 17 00:00:00 2001 From: mingeung Date: Mon, 8 Dec 2025 20:25:19 +0900 Subject: [PATCH 47/61] =?UTF-8?q?feat=20:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20=EC=84=B1=EA=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../codeboy/mvc/config/SecurityConfig.java | 49 +++++++++++-------- .../mvc/controller/JoinController.java | 7 +++ .../java/com/codeboy/mvc/jwt/LoginFilter.java | 47 +++++++++++++++--- 3 files changed, 75 insertions(+), 28 deletions(-) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java index 325f7b4..6109381 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java @@ -3,6 +3,7 @@ import com.codeboy.mvc.jwt.JWTFilter; import com.codeboy.mvc.jwt.JWTUtil; import com.codeboy.mvc.jwt.LoginFilter; +import com.codeboy.mvc.model.service.CustomerUserDetailService; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; @@ -17,14 +18,14 @@ import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -@Configuration -@EnableWebSecurity @RequiredArgsConstructor +@EnableWebSecurity +@Configuration public class SecurityConfig { - private final AuthenticationConfiguration authenticationConfiguration; - private final ObjectMapper objectMapper; // 필요 없으면 지워도 됨 + private final CustomerUserDetailService customerUserDetailService; private final JWTUtil jwtUtil; + private final com.fasterxml.jackson.databind.ObjectMapper objectMapper; // ✅ 추가 @Bean @@ -32,45 +33,51 @@ public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } - // 특정 Http 요청에 대한 웹 기반 보안 구성 + // ✅ AuthenticationManager를 “내 UserDetailsService + BCrypt”로 명시적으로 구성 + @Bean + public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception { + var builder = http.getSharedObject(org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder.class); + + builder + .userDetailsService(customerUserDetailService) + .passwordEncoder(bCryptPasswordEncoder()); + + return builder.build(); + } + @Bean - public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + public SecurityFilterChain securityFilterChain(HttpSecurity http, + AuthenticationManager authenticationManager) throws Exception { - // 기본 제공 로그인/HTTP Basic/CSRF 비활성화 http .formLogin(AbstractHttpConfigurer::disable) .httpBasic(AbstractHttpConfigurer::disable) .csrf(AbstractHttpConfigurer::disable); - // 인가(접근 권한) 설정 http .authorizeHttpRequests(auth -> auth .requestMatchers("/", "/login", "/join").permitAll() - .requestMatchers("/admin").hasRole("ADMIN") // "ADMIB" 오타 수정 + .requestMatchers("/admin/**").hasRole("ADMIN") // ✅ 보통 이렇게 씀 .anyRequest().authenticated() ); - // 세션 사용하지 않는(JWT 등) 방식으로 설정 http .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS) ); - // 커스텀 로그인 필터 추가 (UsernamePasswordAuthenticationFilter 위치에 대체) - AuthenticationManager authenticationManager = - authenticationConfiguration.getAuthenticationManager(); - + // ✅ 로그인 필터에 jwtUtil도 같이 넘겨주는 게 일반적 http.addFilterAt( - new LoginFilter(authenticationManager), + new LoginFilter(authenticationManager, jwtUtil, objectMapper), // ✅ 수정 UsernamePasswordAuthenticationFilter.class ); - return http.build(); - } + // ✅ JWTFilter도 필터 체인에 등록해야, 로그인 이후부터 토큰으로 인증됨 + http.addFilterBefore( + new JWTFilter(jwtUtil, customerUserDetailService), + UsernamePasswordAuthenticationFilter.class + ); - // AuthenticationManager를 Bean으로도 노출하고 싶으면 (선택사항) - @Bean - public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception { - return configuration.getAuthenticationManager(); + return http.build(); } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java index 05af014..0fe517a 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java @@ -29,3 +29,10 @@ public ResponseEntity> adminP(@RequestBody JoinRequest joinReq } } + +//{ +// "id": "testuser", +// "password": "1234", +// "nickname": "테스트유저", +// "email": "test@example.com" +// } \ No newline at end of file diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java index 0c5d299..6d02972 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java @@ -1,5 +1,7 @@ package com.codeboy.mvc.jwt; +import com.codeboy.mvc.model.dto.CustomUserDetails; +import com.codeboy.mvc.model.dto.request.LoginRequest; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -17,6 +19,13 @@ public class LoginFilter extends UsernamePasswordAuthenticationFilter { private final AuthenticationManager authenticationManager; + private final JWTUtil jwtUtil; + private final com.fasterxml.jackson.databind.ObjectMapper objectMapper; // ✅ 추가 + + { + // 인스턴스 초기화 블록 or 생성자에서 설정 + setFilterProcessesUrl("/login"); // ✅ 이 URL로 오는 요청을 로그인으로 처리 + } /** * 로그인 시도 시 호출되는 메서드 @@ -25,10 +34,19 @@ public class LoginFilter extends UsernamePasswordAuthenticationFilter { public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { + // ✅ JSON 바디를 LoginRequest로 파싱 + LoginRequest loginRequest = + null; + try { + loginRequest = objectMapper.readValue(request.getInputStream(), LoginRequest.class); + } catch (IOException e) { + throw new RuntimeException(e); + } + // 기본적으로 UsernamePasswordAuthenticationFilter가 제공하는 메서드 사용 - String username = obtainUsername(request); - String password = obtainPassword(request); + String username = loginRequest.getId(); + String password = loginRequest.getPassword(); // null일 수도 있으니 한 번 더 방어적으로 처리해도 됨 if (username == null) { @@ -59,14 +77,26 @@ protected void successfulAuthentication(HttpServletRequest request, System.out.println("login success: " + authResult.getName()); - // JWT 쓰고 싶으면 여기에서 토큰 만들어서 헤더에 담아주면 됨 - // response.addHeader("Authorization", "Bearer " + token); + // 1) 인증된 사용자 정보 가져오기 + CustomUserDetails principal = (CustomUserDetails) authResult.getPrincipal(); + String username = principal.getUsername(); + String role = principal.getAuthorities().iterator().next().getAuthority(); // 예: "ROLE_USER" - // 기본 흐름 계속 진행 - // (필요에 따라 chain.doFilter 호출 여부 선택) - chain.doFilter(request, response); + // 2) JWT 토큰 생성 (jwtUtil 메서드 형태에 맞게 수정) + // 예시: createJwt(아이디, 역할, 만료시간ms) + String token = jwtUtil.createJwt(username, role, 60 * 60 * 1000L); // 1시간짜리 토큰 + + // 3) 응답 헤더/바디에 토큰 담기 + response.setStatus(HttpServletResponse.SC_OK); + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write("{\"token\":\"" + token + "\"}"); + response.getWriter().flush(); + + // 4) 🔥 더 이상 체인을 안 태운다. 여기서 응답 끝! + // chain.doFilter(request, response); <-- 이건 제거 } + /** * 로그인 실패 시 호출되는 메서드 */ @@ -78,5 +108,8 @@ protected void unsuccessfulAuthentication(HttpServletRequest request, System.out.println("login fail: " + failed.getMessage()); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write("{\"message\":\"로그인에 실패했습니다.\"}"); } + } From 41e9207f78239480814db80e4a0e94a9ecb16a0b Mon Sep 17 00:00:00 2001 From: mingeung Date: Mon, 8 Dec 2025 20:33:22 +0900 Subject: [PATCH 48/61] =?UTF-8?q?fix=20:=20=EB=AC=B8=EC=A0=9C=20=EC=84=A0?= =?UTF-8?q?=EC=A7=80=20=EC=A0=95=EB=8B=B5=20type=EC=9D=84=20String?= =?UTF-8?q?=EC=97=90=EC=84=9C=20int=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/codeboy/mvc/model/dto/Problem.java | 2 +- .../java/com/codeboy/mvc/model/dto/UserProblem.java | 2 +- .../src/main/resources/db/migration/DDL_schema.sql | 13 ++----------- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Problem.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Problem.java index 195d199..605793f 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Problem.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/Problem.java @@ -20,7 +20,7 @@ public class Problem { private String choice2; private String choice3; private String choice4; - private String answer; + private int answerChoice; private Category category; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblem.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblem.java index 85aecc3..ab646ce 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblem.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/UserProblem.java @@ -21,7 +21,7 @@ public class UserProblem { private String choice2; private String choice3; private String choice4; - private String answer; + private int answerChoice; private int commentCount; private Long userProblemSetId; } diff --git a/codeBoy_backend/src/main/resources/db/migration/DDL_schema.sql b/codeBoy_backend/src/main/resources/db/migration/DDL_schema.sql index b7379e2..aea0b48 100644 --- a/codeBoy_backend/src/main/resources/db/migration/DDL_schema.sql +++ b/codeBoy_backend/src/main/resources/db/migration/DDL_schema.sql @@ -10,16 +10,7 @@ SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; --- ----------------------------------------------------- --- Schema mydb --- ----------------------------------------------------- --- ----------------------------------------------------- --- Schema board_test --- ----------------------------------------------------- --- ----------------------------------------------------- --- Schema board_test --- ----------------------------------------------------- CREATE SCHEMA IF NOT EXISTS `board_test` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci ; USE board_test; @@ -92,7 +83,7 @@ CREATE TABLE IF NOT EXISTS `board_test`.`problem` ( `choice_2` VARCHAR(255) NOT NULL, `choice_3` VARCHAR(255) NOT NULL, `choice_4` VARCHAR(255) NOT NULL, - `answer` VARCHAR(10) NOT NULL, + `answer_coice` TINYINT NOT NULL, `category` VARCHAR(50) NOT NULL, PRIMARY KEY (`problem_id`)) ENGINE = InnoDB @@ -190,7 +181,7 @@ CREATE TABLE IF NOT EXISTS `board_test`.`user_problem` ( `choice_2` VARCHAR(255) NOT NULL, `choice_3` VARCHAR(255) NOT NULL, `choice_4` VARCHAR(255) NOT NULL, - `answer` VARCHAR(10) NOT NULL, + `answer_coice` TINYINT NOT NULL, `comment_count` INT NOT NULL DEFAULT 0, `user_problem_set_id` BIGINT NOT NULL, PRIMARY KEY (`user_problem_id`), From f02355c64e2e0f53ff80c23101c54533384d8f05 Mon Sep 17 00:00:00 2001 From: mingeung Date: Mon, 8 Dec 2025 20:48:08 +0900 Subject: [PATCH 49/61] =?UTF-8?q?feat=20:=20=ED=80=B4=EC=A6=88=EB=B0=A9?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=ED=8A=B9=EC=A0=95=20=EB=A9=A4=EB=B2=84=20?= =?UTF-8?q?=EB=82=B4=EB=B3=B4=EB=82=B4=EA=B8=B0=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=84=B1=EA=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mvc/controller/QuizRoomController.java | 17 +++++++++++++ .../codeboy/mvc/model/dao/QuizRoomDao.java | 10 ++++++++ .../mvc/model/service/QuizRoomService.java | 24 +++++++++++++++++++ .../main/resources/mappers/QuizRoomMapper.xml | 22 +++++++++++++++++ 4 files changed, 73 insertions(+) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java index f892631..c7bfb3f 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java @@ -104,4 +104,21 @@ public ResponseEntity> deleteQuizRoom(@PathVariable long roo return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); } } + //퀴즈방에서 나가기 + // 퀴즈방에서 나가기 + @DeleteMapping("/{roomId}/member/{memberId}") + public ResponseEntity> leaveQuizRoom(@PathVariable long roomId, + @PathVariable long memberId) { + try { + quizRoomService.leaveQuizRoom(roomId, memberId); + return ResponseEntity + .status(HttpStatus.OK) + .body(ApiResponse.success(HttpStatus.OK, "퀴즈방에서 성공적으로 나갔습니다.")); + } catch (IllegalArgumentException | IllegalStateException e) { + return ResponseEntity + .status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); + } + } + } \ No newline at end of file diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java index 60f8a2d..db92ead 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dao/QuizRoomDao.java @@ -6,6 +6,7 @@ import com.codeboy.mvc.model.dto.QuizRoomMember; import com.codeboy.mvc.model.dto.response.GetQuizRoomMembersResponse; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; @Mapper public interface QuizRoomDao { @@ -32,4 +33,13 @@ public interface QuizRoomDao { //퀴즈룸에 특정 멤버가 있는지 확인 public int isDuplicatedMember(Long memberId); + + QuizRoomMember selectQuizRoomMember(@Param("roomId") long roomId, + @Param("memberId") long memberId); + + /** + * 퀴즈방 멤버 테이블에서 특정 멤버를 삭제 (퇴장) + */ + int deleteQuizRoomMember(@Param("roomId") long roomId, + @Param("memberId") long memberId); } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java index ea246e0..c66dde8 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/QuizRoomService.java @@ -82,4 +82,28 @@ private void memberDuplicateCheck(Long memberId) { } } + public void leaveQuizRoom(long roomId, long memberId) { + + // 1) 현재 방에 이 멤버가 실제로 있는지 확인 + QuizRoomMember quizRoomMember = quizRoomDao.selectQuizRoomMember(roomId, memberId); + + if (quizRoomMember == null) { + throw new IllegalArgumentException("해당 멤버는 이 퀴즈방에 참가 중이 아닙니다."); + } + + // TODO: 호스트가 나갈 때의 정책이 따로 있다면 여기서 처리 + // if (quizRoomMember.getIsHost()) { ... } + + // 2) 퀴즈방 멤버 목록에서 삭제 + int deleted = quizRoomDao.deleteQuizRoomMember(roomId, memberId); + + if (deleted != 1) { + throw new IllegalStateException("퀴즈방 퇴장 처리에 실패했습니다."); + } + + // TODO: 마지막 사람이 나가면 방 자체를 삭제할지 여부는 여기서 추가로 정책 결정 가능 + // int remains = quizRoomDao.countMembersInRoom(roomId); + // if (remains == 0) { quizRoomDao.deleteQuizRoom(roomId); } + } + } diff --git a/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml b/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml index 29115a6..a89ba62 100644 --- a/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/QuizRoomMapper.xml @@ -62,5 +62,27 @@ WHERE member_id = #{memberId} + + + + + + DELETE FROM quiz_room_member + WHERE room_id = #{roomId} + AND member_id = #{memberId} + + + \ No newline at end of file From b2ebf20a4423bfbb2b7b6e828483ce745d4c9ae6 Mon Sep 17 00:00:00 2001 From: mingeung Date: Mon, 8 Dec 2025 21:04:13 +0900 Subject: [PATCH 50/61] =?UTF-8?q?feat=20:=20controller=EC=97=90=EC=84=9C?= =?UTF-8?q?=20memberId=20=EB=B0=9B=EC=95=84=EC=98=A4=EB=8A=94=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20spring=20security=EC=97=90=EC=84=9C=20=EB=B0=9B?= =?UTF-8?q?=EC=95=84=EC=98=A4=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mvc/controller/CommentController.java | 15 ++++++----- .../controller/IncorrectNoteController.java | 13 ++++----- .../mvc/controller/MemberController.java | 21 ++++++++------- .../mvc/controller/QuizRoomController.java | 20 +++++++------- .../mvc/controller/UserProblemController.java | 14 +++++----- .../controller/UserProblemSetController.java | 14 +++++----- .../mvc/controller/UserScoreController.java | 27 ++++++++----------- .../mvc/model/dto/CustomUserDetails.java | 5 ++++ .../dto/request/JoinQuizRoomRequest.java | 1 - 9 files changed, 70 insertions(+), 60 deletions(-) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java index c329651..ccd3a0e 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/CommentController.java @@ -3,12 +3,14 @@ import java.util.ArrayList; import java.util.List; +import com.codeboy.mvc.model.dto.CustomUserDetails; import com.codeboy.mvc.model.dto.request.CommentUpdateRequest; import com.codeboy.mvc.model.dto.response.ApiResponse; import jakarta.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; @@ -53,12 +55,13 @@ public ResponseEntity>> getAllCommentsById(@PathVariab @PostMapping("{userProblemSetId}") public ResponseEntity> addComment(@PathVariable long userProblemSetId, - @RequestBody Comment comment, HttpSession session) { + @RequestBody Comment comment, @AuthenticationPrincipal CustomUserDetails loginUser) { if (comment.getContent() == null || comment.getContent().isBlank()) { return ResponseEntity.status(HttpStatus.BAD_REQUEST) .body(ApiResponse.failure(HttpStatus.BAD_REQUEST, "댓글 내용은 비어 있을 수 없습니다.")); } - Long memberId = (Long) session.getAttribute("memberId"); + + Long memberId = loginUser.getMemberId(); if (memberId == null) { // 인증 안 됨 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) @@ -83,9 +86,9 @@ public ResponseEntity> updateComment( @PathVariable long userProblemSetId, @PathVariable long commentId, @RequestBody CommentUpdateRequest commentUpdateRequest, - HttpSession session) { + @AuthenticationPrincipal CustomUserDetails loginUser) { - Long memberId = (Long) session.getAttribute("memberId"); + Long memberId = loginUser.getMemberId(); if (memberId == null) { // 인증 안 됨 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) @@ -124,9 +127,9 @@ public ResponseEntity> updateComment( @DeleteMapping("{userProblemSetId}/{commentId}") public ResponseEntity> deleteComment(@PathVariable long userProblemSetId, @PathVariable long commentId, - HttpSession session) { + @AuthenticationPrincipal CustomUserDetails loginUser) { - Long memberId = (Long) session.getAttribute("memberId"); + Long memberId = loginUser.getMemberId(); // 로그인 안한 상태 if (memberId == null) { diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java index 405b907..3bddc25 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/IncorrectNoteController.java @@ -1,5 +1,6 @@ package com.codeboy.mvc.controller; +import com.codeboy.mvc.model.dto.CustomUserDetails; import com.codeboy.mvc.model.dto.request.IncorrectNoteRequest; import com.codeboy.mvc.model.dto.response.ApiResponse; import com.codeboy.mvc.model.dto.response.IncorrectNoteResponse; @@ -11,6 +12,7 @@ import org.apache.ibatis.javassist.NotFoundException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -28,10 +30,9 @@ public IncorrectNoteController(IncorrectNoteService incorrectNoteService) { //한 회원의 오답노트를 모두 조회 @GetMapping - public ResponseEntity>> getIncorrectNote(HttpSession session) { + public ResponseEntity>> getIncorrectNote( @AuthenticationPrincipal CustomUserDetails loginUser) { try { - //TODO : 세션 or spring security에서 memberId 가져오기 - Long memberId = (Long) session.getAttribute("memberId"); + Long memberId = loginUser.getMemberId(); List incorrectNoteList = incorrectNoteService.getIncorrectNoteList(memberId); return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "오답노트가 성공적으로 조회되었습니다", incorrectNoteList)); } catch (IllegalArgumentException e) { @@ -43,9 +44,9 @@ public ResponseEntity>> getIncorrectNote //오답노트에 문제 넣기 @PostMapping - public ResponseEntity> addIncorrectNote(@RequestBody IncorrectNoteRequest incorrectNoteRequest, HttpSession session) { - //TODO : 세션에서 멤버 id 가져오기 - Long memberId = (Long) session.getAttribute("memberId"); + public ResponseEntity> addIncorrectNote(@RequestBody IncorrectNoteRequest incorrectNoteRequest, @AuthenticationPrincipal CustomUserDetails loginUser) { + + Long memberId = loginUser.getMemberId(); Long problemId = incorrectNoteRequest.getProblemId(); Long userProblemId = incorrectNoteRequest.getUserProblemId(); Boolean isUserProblem = incorrectNoteRequest.getIsUserProblem(); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java index 65e265d..dc4368e 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java @@ -1,6 +1,7 @@ package com.codeboy.mvc.controller; +import com.codeboy.mvc.model.dto.CustomUserDetails; import com.codeboy.mvc.model.dto.Member; import com.codeboy.mvc.model.dto.request.DuplicateCheckRequest; import com.codeboy.mvc.model.dto.request.LoginRequest; @@ -16,6 +17,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import com.codeboy.mvc.model.service.MemberService; @@ -133,10 +135,10 @@ public ResponseEntity> logout(HttpSession session) { * 401 인증 실패 */ //회원정보 전체를 업데이트하지않고 일부만 수정하는 거라서 Put에서 Patch매핑으로 변경 - @PatchMapping("/members/{memberId}") - public ResponseEntity updateMe(@RequestBody MemberUpdateRequest request, @PathVariable long memberId ) { + @PatchMapping("/members") + public ResponseEntity updateMe(@RequestBody MemberUpdateRequest request, @AuthenticationPrincipal CustomUserDetails loginUser) { //파라미터로 memberId받아서 해당회원의 정보를 수정 - + Long memberId = loginUser.getMemberId(); Member member = memberService.getMemberById(memberId); //회원을 못찾는 경우 ->존재하지 않는 memberId인경우 if (member == null) { @@ -166,8 +168,8 @@ public ResponseEntity updateMe(@RequestBody MemberUpdateRequest request, @Pat //회원 조회 @GetMapping("/members/") - public ResponseEntity> getMemberInfo(HttpSession session) { - Long memberId = 1L; + public ResponseEntity> getMemberInfo( @AuthenticationPrincipal CustomUserDetails loginUser) { + Long memberId = loginUser.getMemberId(); try { Member member = memberService.getMemberById(memberId); return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "회원정보가 조회되었습니다", member)); @@ -182,9 +184,9 @@ public ResponseEntity> getMemberInfo(HttpSession session) { //회원 탈퇴 @DeleteMapping - public ResponseEntity> deleteMember() { + public ResponseEntity> deleteMember( @AuthenticationPrincipal CustomUserDetails loginUser) { //TODO : memberId 받아오기 - Long memberId = 1L; + Long memberId = loginUser.getMemberId(); try { memberService.deactivateMember(memberId); return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "회원이 성공적으로 삭제되었습니다.")); @@ -198,9 +200,8 @@ public ResponseEntity> deleteMember() { //회원 정보 업데이트 @PatchMapping - public ResponseEntity> updateMember(@RequestBody MemberUpdateRequest request) { - //TODO : memberId 받아오기 - Long memberId = 1L; + public ResponseEntity> updateMember(@RequestBody MemberUpdateRequest request, @AuthenticationPrincipal CustomUserDetails loginUser) { + Long memberId = loginUser.getMemberId(); try { memberService.updateMember(memberId, request); return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(HttpStatus.OK, "회원정보 업데이트에 성공했습니다.")); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java index c7bfb3f..20f899e 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/QuizRoomController.java @@ -8,6 +8,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -24,12 +25,13 @@ public QuizRoomController(QuizRoomService quizRoomService) { //호스트 - 퀴즈방 만들기 //TODO : 테스트용으로 memberId를 PathVariable로 넘김 - @PostMapping("/create/{memberId}") + @PostMapping("/create") //TODO : 로그인 구현되면 memberId를 requestBody로 넘기지 말고 세션에서 가져오도록 하기 - public ResponseEntity> createQuizRoom(@PathVariable long memberId) { + public ResponseEntity> createQuizRoom(@AuthenticationPrincipal CustomUserDetails loginUser) { try { + Long memberId = loginUser.getMemberId(); //새로운 채팅방 생성하기 - long quizRoomId = quizRoomService.createQuizRoom(); + Long quizRoomId = quizRoomService.createQuizRoom(); //3. QuizRoomMember 객체 생성 // Long memberId = 1L; QuizRoomMember quizRoomMember = new QuizRoomMember(); @@ -48,11 +50,10 @@ public ResponseEntity> createQuizRoom(@PathVariable long membe } //채팅방 참여하기 - @PostMapping("/join") + @PostMapping("/join/{roomId}") //TODO : 로그인 구현되면 memberId를 requestBody로 넘기지 말고 세션에서 가져오도록 하기 - public ResponseEntity> joinQuizRoom(@RequestBody JoinQuizRoomRequest request) { - long memberId = request.getMemberId(); - long roomId = request.getRoomId(); + public ResponseEntity> joinQuizRoom(@PathVariable Long roomId, @AuthenticationPrincipal CustomUserDetails loginUser) { + Long memberId = loginUser.getMemberId(); try { //QuizRoomMember 생성 QuizRoomMember quizRoomMember = new QuizRoomMember(); @@ -106,9 +107,10 @@ public ResponseEntity> deleteQuizRoom(@PathVariable long roo } //퀴즈방에서 나가기 // 퀴즈방에서 나가기 - @DeleteMapping("/{roomId}/member/{memberId}") + @DeleteMapping("/{roomId}/member") public ResponseEntity> leaveQuizRoom(@PathVariable long roomId, - @PathVariable long memberId) { + @AuthenticationPrincipal CustomUserDetails loginUser) { + Long memberId = loginUser.getMemberId(); try { quizRoomService.leaveQuizRoom(roomId, memberId); return ResponseEntity diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java index 5c3b423..017a450 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemController.java @@ -1,5 +1,6 @@ package com.codeboy.mvc.controller; +import com.codeboy.mvc.model.dto.CustomUserDetails; import com.codeboy.mvc.model.dto.UserProblem; import com.codeboy.mvc.model.dto.response.ApiResponse; // 실제 패키지에 맞게 수정 import com.codeboy.mvc.model.service.UserProblemService; @@ -8,6 +9,7 @@ import jakarta.servlet.http.HttpSession; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -51,9 +53,9 @@ public ResponseEntity>> getProblemsByUserProblemSe public ResponseEntity> createUserProblems( @PathVariable Long userProblemSetId, @RequestBody List userProblems, - HttpSession session + @AuthenticationPrincipal CustomUserDetails loginUser ) { - Long memberId = (Long) session.getAttribute("memberId"); + Long memberId= loginUser.getMemberId(); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); @@ -89,9 +91,9 @@ public ResponseEntity> createUserProblems( public ResponseEntity> updateUserProblem( @PathVariable Long userProblemId, @RequestBody UserProblem userProblem, - HttpSession session + @AuthenticationPrincipal CustomUserDetails loginUser ) { - Long memberId = (Long) session.getAttribute("memberId"); + Long memberId= loginUser.getMemberId(); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); @@ -123,9 +125,9 @@ public ResponseEntity> updateUserProblem( @DeleteMapping("/{userProblemId}") public ResponseEntity> deleteUserProblem( @PathVariable Long userProblemId, - HttpSession session + @AuthenticationPrincipal CustomUserDetails loginUser ) { - Long memberId = (Long) session.getAttribute("memberId"); + Long memberId= loginUser.getMemberId(); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java index c240bbd..10802e1 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserProblemSetController.java @@ -1,5 +1,6 @@ package com.codeboy.mvc.controller; +import com.codeboy.mvc.model.dto.CustomUserDetails; import com.codeboy.mvc.model.dto.UserProblemSet; import com.codeboy.mvc.model.dto.response.ApiResponse; // 실제 패키지에 맞게 수정 import com.codeboy.mvc.model.service.UserProblemSetService; @@ -10,6 +11,7 @@ import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -41,8 +43,8 @@ public ResponseEntity>> getAllUserProblemSets() // 마이페이지 - 내가 만든 문제세트 조회 @GetMapping("/me") - public ResponseEntity>> getMyUserProblemSet(HttpSession session) { - Long memberId = (Long) session.getAttribute("memberId"); + public ResponseEntity>> getMyUserProblemSet( @AuthenticationPrincipal CustomUserDetails loginUser) { + Long memberId = loginUser.getMemberId(); System.out.println(memberId); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) @@ -68,8 +70,8 @@ public ResponseEntity>> getMyUserProblemSet(Htt // 마이페이지 - 문제세트 생성 @PostMapping - public ResponseEntity> createMyUserProblemSet(HttpSession session) { - Long memberId = (Long) session.getAttribute("memberId"); + public ResponseEntity> createMyUserProblemSet(HttpSession session, @AuthenticationPrincipal CustomUserDetails loginUser) { + Long memberId = loginUser.getMemberId(); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); @@ -110,9 +112,9 @@ public ResponseEntity> createMyUserProblemSet(HttpSession session @DeleteMapping("/{userProblemSetId}") public ResponseEntity> deleteUserProblemSet( @PathVariable Long userProblemSetId, - HttpSession session + @AuthenticationPrincipal CustomUserDetails loginUser ) { - Long memberId = (Long) session.getAttribute("memberId"); + Long memberId= loginUser.getMemberId(); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java index 3e2948f..a5eccbb 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java @@ -2,8 +2,10 @@ import java.util.List; +import com.codeboy.mvc.model.dto.CustomUserDetails; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import com.codeboy.mvc.model.dto.UserScore; @@ -30,9 +32,9 @@ public UserScoreController(UserScoreService userScoreService) { @PostMapping public ResponseEntity> createUserScore( @RequestBody UserScore userScore, - HttpSession session + @AuthenticationPrincipal CustomUserDetails loginUser ) { - Long memberId = (Long) session.getAttribute("memberId"); + Long memberId = loginUser.getMemberId(); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); @@ -67,8 +69,8 @@ public ResponseEntity> createUserScore( // 전체 유저 점수 조회 @GetMapping - public ResponseEntity>> getAllUserScores(HttpSession session) { - Long memberId = (Long) session.getAttribute("memberId"); + public ResponseEntity>> getAllUserScores( @AuthenticationPrincipal CustomUserDetails loginUser) { + Long memberId = loginUser.getMemberId(); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); @@ -92,18 +94,11 @@ public ResponseEntity>> getAllUserScores(HttpSession } // 특정 유저 점수 조회 - @GetMapping("/{memberId}") + @GetMapping public ResponseEntity> getUserScore( - @PathVariable Long memberId, - HttpSession session + @AuthenticationPrincipal CustomUserDetails loginUser ) { - Long loginMemberId = (Long) session.getAttribute("memberId"); - if (loginMemberId == null) { - return ResponseEntity.status(HttpStatus.UNAUTHORIZED) - .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); - } - - + Long memberId = loginUser.getMemberId(); try { UserScore userScore = userScoreService.getUserScoreById(memberId); @@ -130,9 +125,9 @@ public ResponseEntity> getUserScore( @PutMapping public ResponseEntity> updateUserScore( @RequestBody UserScore userScore, - HttpSession session + @AuthenticationPrincipal CustomUserDetails loginUser ) { - Long memberId = (Long) session.getAttribute("memberId"); + Long memberId = loginUser.getMemberId(); if (memberId == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다.")); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CustomUserDetails.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CustomUserDetails.java index 7e63a91..6751501 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CustomUserDetails.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CustomUserDetails.java @@ -26,6 +26,11 @@ public String getAuthority() { }); return collection; } + + public Long getMemberId() { + return member.getMemberId(); // member 엔티티에 memberId 필드 있다고 가정 + } + @Override public String getPassword() { return member.getPassword(); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/JoinQuizRoomRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/JoinQuizRoomRequest.java index 079bd8c..4e0d70d 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/JoinQuizRoomRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/JoinQuizRoomRequest.java @@ -8,7 +8,6 @@ @Setter @ToString public class JoinQuizRoomRequest { - private long memberId; private long roomId; } From 2c07e89d70788d23c436238470ae164870e29ecf Mon Sep 17 00:00:00 2001 From: mingeung Date: Tue, 9 Dec 2025 16:41:12 +0900 Subject: [PATCH 51/61] =?UTF-8?q?fix=20:=20member=20controller=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85,=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8,=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=82=AD=EC=A0=9C=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codeBoy_backend/pom.xml | 79 ++++++----------- .../codeboy/mvc/config/SecurityConfig.java | 14 ++- .../mvc/controller/JoinController.java | 11 +-- .../mvc/controller/MemberController.java | 88 +------------------ .../mvc/controller/UserScoreController.java | 2 +- .../java/com/codeboy/mvc/jwt/JWTFilter.java | 4 +- .../java/com/codeboy/mvc/jwt/LoginFilter.java | 10 +-- .../service/CustomerUserDetailService.java | 2 - .../mvc/model/service/JoinService.java | 6 +- 9 files changed, 43 insertions(+), 173 deletions(-) diff --git a/codeBoy_backend/pom.xml b/codeBoy_backend/pom.xml index 8fae8d8..29abeb6 100644 --- a/codeBoy_backend/pom.xml +++ b/codeBoy_backend/pom.xml @@ -29,60 +29,26 @@ 17 - - - org.springframework.boot - spring-boot-starter-web - - - org.mybatis.spring.boot - mybatis-spring-boot-starter - 3.0.5 - - - org.springframework.boot - spring-boot-devtools - runtime - true - - - com.mysql - mysql-connector-j - runtime - - - org.springframework.boot - spring-boot-starter-test - test - - - org.mybatis.spring.boot - mybatis-spring-boot-starter-test - 3.0.5 - test - + + com.mysql mysql-connector-j runtime + + org.springframework.boot + spring-boot-starter-web + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 3.0.5 + - - org.springdoc - springdoc-openapi-starter-webmvc-ui - 2.3.0 - - - org.springframework.boot - spring-boot-starter - - - org.projectlombok - lombok - 1.18.42 - - org.springframework.boot spring-boot-starter-security + io.jsonwebtoken jjwt-api @@ -96,10 +62,23 @@ io.jsonwebtoken - jjwt-jackson + jjwt-jackson 0.12.3 runtime + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.3.0 + + + + org.projectlombok + lombok + 1.18.42 + + org.flywaydb flyway-core @@ -109,10 +88,10 @@ flyway-mysql + - - + org.springframework.boot diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java index 6109381..355ba7d 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java @@ -4,12 +4,10 @@ import com.codeboy.mvc.jwt.JWTUtil; import com.codeboy.mvc.jwt.LoginFilter; import com.codeboy.mvc.model.service.CustomerUserDetailService; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; @@ -25,7 +23,7 @@ public class SecurityConfig { private final CustomerUserDetailService customerUserDetailService; private final JWTUtil jwtUtil; - private final com.fasterxml.jackson.databind.ObjectMapper objectMapper; // ✅ 추가 + private final com.fasterxml.jackson.databind.ObjectMapper objectMapper; // @Bean @@ -33,7 +31,6 @@ public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } - // ✅ AuthenticationManager를 “내 UserDetailsService + BCrypt”로 명시적으로 구성 @Bean public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception { var builder = http.getSharedObject(org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder.class); @@ -56,7 +53,10 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http, http .authorizeHttpRequests(auth -> auth - .requestMatchers("/", "/login", "/join").permitAll() + .requestMatchers("/", "/login", "/join", "/swagger-ui/**", + "/v3/api-docs/**", + "/api-docs/**", + "/swagger-resources/**").permitAll() .requestMatchers("/admin/**").hasRole("ADMIN") // ✅ 보통 이렇게 씀 .anyRequest().authenticated() ); @@ -66,13 +66,11 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http, session.sessionCreationPolicy(SessionCreationPolicy.STATELESS) ); - // ✅ 로그인 필터에 jwtUtil도 같이 넘겨주는 게 일반적 http.addFilterAt( - new LoginFilter(authenticationManager, jwtUtil, objectMapper), // ✅ 수정 + new LoginFilter(authenticationManager, jwtUtil, objectMapper), UsernamePasswordAuthenticationFilter.class ); - // ✅ JWTFilter도 필터 체인에 등록해야, 로그인 이후부터 토큰으로 인증됨 http.addFilterBefore( new JWTFilter(jwtUtil, customerUserDetailService), UsernamePasswordAuthenticationFilter.class diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java index 0fe517a..a8844f2 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java @@ -25,14 +25,5 @@ public ResponseEntity> adminP(@RequestBody JoinRequest joinReq } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.failure(HttpStatus.BAD_REQUEST, e.getMessage())); } - } - -} - -//{ -// "id": "testuser", -// "password": "1234", -// "nickname": "테스트유저", -// "email": "test@example.com" -// } \ No newline at end of file +} \ No newline at end of file diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java index dc4368e..d93880a 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java @@ -39,92 +39,7 @@ public MemberController(MemberService memberService) { this.memberService = memberService; } - /** - * 회원가입 - * POST /api/members - * RequestBody: { id, password, nickname, email } - * Response: - * 201 생성 성공 - * 400 잘못된 요청 - * 409 아이디/이메일 중복 - */ - @PostMapping("/member") - public ResponseEntity signUp(@RequestBody Member member) { - // TODO: 아이디/이메일 중복 체크 로직은 나중에 추가 - int result = memberService.signUp(member); - - if (result == 1) { - // Location 헤더에 새로 생성된 리소스 URI 넣어줄 수도 있음 - URI location = URI.create("/api/members/" + member.getMemberId()); - - return ResponseEntity - .status(HttpStatusCode.valueOf(201)) - .location(location) - .body("회원가입 성공"); - } else { - return ResponseEntity - .status(HttpStatusCode.valueOf(400)) - .body("회원가입 실패"); - } - //아이디/이메일 중복로직은 나중에 구 - } - /** - * 로그인 - * POST /api/auth/login - * RequestBody: { id, password } - * Response: - * 200 성공 시 { token, memberId, nickname } - * 401 실패 시 { error: "로그인 실패" } - */ - @PostMapping("/auth/login") - public ResponseEntity> login(@RequestBody LoginRequest request, HttpSession session) { - try { - // Service를 통해 로그인 처리 - Member member = memberService.login(request.getId(), request.getPassword()); - - // 세션에 member_id 저장 - session.setAttribute("memberId", member.getMemberId()); - session.setAttribute("id", member.getId()); - session.setAttribute("nickname", member.getNickname()); - - // 성공 응답 반환 - - return ResponseEntity.status(HttpStatus.OK) - .body(ApiResponse.success(HttpStatus.OK, "로그인 성공", - new HashMap() {private static final long serialVersionUID = 5698154608853982208L; - - { - put("memberId", member.getMemberId()); - put("nickname", member.getNickname()); - put("id", member.getId()); - }})); - } catch (IllegalArgumentException e) { - // 로그인 실패 (ID/비밀번호 오류 등) - return ResponseEntity.status(HttpStatus.UNAUTHORIZED) - .body(ApiResponse.failure(HttpStatus.UNAUTHORIZED, e.getMessage())); - } catch (Exception e) { - // 기타 오류 - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body(ApiResponse.failure(HttpStatus.INTERNAL_SERVER_ERROR, "로그인 처리 중 오류가 발생했습니다.")); - } - } - /** - * 로그아웃 - * POST /api/auth/logout - * RequestBody: 없음 - * Response: - * 204 성공 시 본문 없음 - */ - @PostMapping("/auth/logout") - public ResponseEntity> logout(HttpSession session) { - // 세션 무효화 - session.invalidate(); - - return ResponseEntity.status(HttpStatus.OK) - .body(ApiResponse.success(HttpStatus.OK, "로그아웃 성공", null)); - - } /** * 내 정보 수정 * PUT /api/members/me @@ -167,7 +82,7 @@ public ResponseEntity updateMe(@RequestBody MemberUpdateRequest request, @Au } //회원 조회 - @GetMapping("/members/") + @GetMapping("/members") public ResponseEntity> getMemberInfo( @AuthenticationPrincipal CustomUserDetails loginUser) { Long memberId = loginUser.getMemberId(); try { @@ -185,7 +100,6 @@ public ResponseEntity> getMemberInfo( @AuthenticationPrincip //회원 탈퇴 @DeleteMapping public ResponseEntity> deleteMember( @AuthenticationPrincipal CustomUserDetails loginUser) { - //TODO : memberId 받아오기 Long memberId = loginUser.getMemberId(); try { memberService.deactivateMember(memberId); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java index a5eccbb..78cb89f 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/UserScoreController.java @@ -94,7 +94,7 @@ public ResponseEntity>> getAllUserScores( @Authentic } // 특정 유저 점수 조회 - @GetMapping + @GetMapping("/member") public ResponseEntity> getUserScore( @AuthenticationPrincipal CustomUserDetails loginUser ) { diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/JWTFilter.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/JWTFilter.java index dfd75c6..61e53f3 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/JWTFilter.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/JWTFilter.java @@ -31,7 +31,7 @@ protected void doFilterInternal(HttpServletRequest request, // 2. 토큰이 없거나 Bearer 형식이 아니면 → 그냥 다음 필터로 넘기고 끝 if (authorization == null || !authorization.startsWith("Bearer ")) { - // System.out.println("JWTFilter: 토큰 없음"); + System.out.println("JWTFilter: 토큰 없음"); filterChain.doFilter(request, response); return; } @@ -41,7 +41,7 @@ protected void doFilterInternal(HttpServletRequest request, // 4. 토큰 만료 여부 검사 if (jwtUtil.isExpired(token)) { - // System.out.println("JWTFilter: 토큰 만료"); + System.out.println("JWTFilter: 토큰 만료"); filterChain.doFilter(request, response); return; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java index 6d02972..7219301 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java @@ -34,7 +34,7 @@ public class LoginFilter extends UsernamePasswordAuthenticationFilter { public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { - // ✅ JSON 바디를 LoginRequest로 파싱 + LoginRequest loginRequest = null; try { @@ -43,12 +43,9 @@ public Authentication attemptAuthentication(HttpServletRequest request, throw new RuntimeException(e); } - - // 기본적으로 UsernamePasswordAuthenticationFilter가 제공하는 메서드 사용 String username = loginRequest.getId(); String password = loginRequest.getPassword(); - // null일 수도 있으니 한 번 더 방어적으로 처리해도 됨 if (username == null) { username = request.getParameter("username"); } @@ -56,11 +53,9 @@ public Authentication attemptAuthentication(HttpServletRequest request, password = request.getParameter("password"); } - // 인증 객체 생성 (권한 컬렉션은 null 또는 빈 리스트로 전달) UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); - // AuthenticationManager에게 실제 인증 위임 return authenticationManager.authenticate(authRequest); } @@ -91,9 +86,6 @@ protected void successfulAuthentication(HttpServletRequest request, response.setContentType("application/json;charset=UTF-8"); response.getWriter().write("{\"token\":\"" + token + "\"}"); response.getWriter().flush(); - - // 4) 🔥 더 이상 체인을 안 태운다. 여기서 응답 끝! - // chain.doFilter(request, response); <-- 이건 제거 } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CustomerUserDetailService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CustomerUserDetailService.java index 4fe9520..96b2b63 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CustomerUserDetailService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/CustomerUserDetailService.java @@ -13,7 +13,6 @@ @RequiredArgsConstructor public class CustomerUserDetailService implements UserDetailsService { - // MemberDao는 Spring이 주입해야 함 (NEW 하면 안됨) private final MemberDao memberDao; @Override @@ -24,7 +23,6 @@ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundEx if (userData == null) { throw new UsernameNotFoundException("User not found: " + username); } - return new CustomUserDetails(userData); } } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java index 8a744e6..5697242 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/JoinService.java @@ -17,15 +17,14 @@ public class JoinService { public Long joinProcess(JoinRequest req) { - - // 2) 중복 아이디 체크 + // 1) 중복 아이디 체크 Boolean exists = memberDao.existByUserId(req.getId()); if (Boolean.TRUE.equals(exists)) { throw new IllegalArgumentException("이미 존재하는 아이디입니다."); } - // 3) Member 매핑 + // 2) Member 매핑 Member member = new Member(); member.setId(req.getId()); member.setPassword(bCryptPasswordEncoder.encode(req.getPassword())); @@ -37,7 +36,6 @@ public Long joinProcess(JoinRequest req) { // 3) DB Insert int rows = memberDao.insertMember(member); if (rows != 1) { - // 혹시 모를 예외 상황 방어 throw new IllegalStateException("회원 가입에 실패했습니다. (insert rows = " + rows + ")"); } From c7f8f5a8db4061505e05340e1c4859e933c61cdf Mon Sep 17 00:00:00 2001 From: mingeung Date: Tue, 9 Dec 2025 17:15:31 +0900 Subject: [PATCH 52/61] =?UTF-8?q?feat=20:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?response=20dto=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/codeboy/mvc/jwt/LoginFilter.java | 36 +++++++++++++------ .../mvc/model/dto/CustomUserDetails.java | 4 +++ .../mvc/model/dto/response/LoginResponse.java | 14 ++++++++ 3 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/LoginResponse.java diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java index 7219301..b9b6ad9 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java @@ -2,11 +2,14 @@ import com.codeboy.mvc.model.dto.CustomUserDetails; import com.codeboy.mvc.model.dto.request.LoginRequest; +import com.codeboy.mvc.model.dto.response.ApiResponse; +import com.codeboy.mvc.model.dto.response.LoginResponse; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -72,20 +75,30 @@ protected void successfulAuthentication(HttpServletRequest request, System.out.println("login success: " + authResult.getName()); - // 1) 인증된 사용자 정보 가져오기 + // 1) 인증된 사용자 정보 CustomUserDetails principal = (CustomUserDetails) authResult.getPrincipal(); String username = principal.getUsername(); - String role = principal.getAuthorities().iterator().next().getAuthority(); // 예: "ROLE_USER" + String role = principal.getAuthorities().iterator().next().getAuthority(); - // 2) JWT 토큰 생성 (jwtUtil 메서드 형태에 맞게 수정) - // 예시: createJwt(아이디, 역할, 만료시간ms) - String token = jwtUtil.createJwt(username, role, 60 * 60 * 1000L); // 1시간짜리 토큰 + // 2) JWT 생성 + String token = jwtUtil.createJwt(username, role, 60 * 60 * 1000L); - // 3) 응답 헤더/바디에 토큰 담기 + // 3) LoginResponse 생성 + LoginResponse loginResponse = new LoginResponse( + token, + principal.getMemberId(), + principal.getUsername(), // 혹은 username + principal.getNickname() + ); + + // 4) ApiResponse 생성 + ApiResponse apiResponse = + ApiResponse.success(HttpStatus.OK, "로그인 성공", loginResponse); + + // 5) JSON으로 내려주기 response.setStatus(HttpServletResponse.SC_OK); response.setContentType("application/json;charset=UTF-8"); - response.getWriter().write("{\"token\":\"" + token + "\"}"); - response.getWriter().flush(); + objectMapper.writeValue(response.getWriter(), apiResponse); } @@ -99,9 +112,12 @@ protected void unsuccessfulAuthentication(HttpServletRequest request, throws IOException, ServletException { System.out.println("login fail: " + failed.getMessage()); + + ApiResponse apiResponse = + ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인에 실패했습니다."); // or failed.getMessage() + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("application/json;charset=UTF-8"); - response.getWriter().write("{\"message\":\"로그인에 실패했습니다.\"}"); + objectMapper.writeValue(response.getWriter(), apiResponse); } - } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CustomUserDetails.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CustomUserDetails.java index 6751501..a353a8b 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CustomUserDetails.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/CustomUserDetails.java @@ -26,6 +26,10 @@ public String getAuthority() { }); return collection; } + public String getNickname() { + return member.getNickname(); + } + public Long getMemberId() { return member.getMemberId(); // member 엔티티에 memberId 필드 있다고 가정 diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/LoginResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/LoginResponse.java new file mode 100644 index 0000000..aa712fc --- /dev/null +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/LoginResponse.java @@ -0,0 +1,14 @@ +package com.codeboy.mvc.model.dto.response; + +// 예: com.codeboy.mvc.model.dto.response 패키지에 둔다 +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class LoginResponse { + private String accessToken; + private Long memberId; + private String id; + private String nickname; +} From 372d0aca9a7b374ea446e28fbb33eb7abf4bc502 Mon Sep 17 00:00:00 2001 From: mingeung Date: Tue, 9 Dec 2025 17:21:33 +0900 Subject: [PATCH 53/61] =?UTF-8?q?fix=20:=20CORS=20Error=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../codeboy/mvc/config/SecurityConfig.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java index 355ba7d..8a62da3 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java @@ -15,6 +15,11 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.List; @RequiredArgsConstructor @EnableWebSecurity @@ -49,7 +54,9 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http, http .formLogin(AbstractHttpConfigurer::disable) .httpBasic(AbstractHttpConfigurer::disable) - .csrf(AbstractHttpConfigurer::disable); + .csrf(AbstractHttpConfigurer::disable) + .cors(cors -> cors.configurationSource(corsConfigurationSource())); + http .authorizeHttpRequests(auth -> auth @@ -78,4 +85,21 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http, return http.build(); } + @Bean + public CorsConfigurationSource corsConfigurationSource() { + CorsConfiguration configuration = new CorsConfiguration(); + + // 프론트 주소 허용 + configuration.setAllowedOrigins(List.of("http://localhost:5173")); + // 모든 메서드 허용 + configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")); + // 모든 헤더 허용 + configuration.setAllowedHeaders(List.of("*")); + // 쿠키/Authorization 헤더 허용 (JWT 쓸 때 보통 true) + configuration.setAllowCredentials(true); + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", configuration); + return source; + } } From ba25d7d040949660ccd5ababc7eb5ab2d725a48c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=A4=80=ED=98=95?= <109512586+junhyung8795@users.noreply.github.com> Date: Wed, 10 Dec 2025 09:44:08 +0900 Subject: [PATCH 54/61] =?UTF-8?q?docs:=20DB=20=EC=8A=A4=ED=82=A4=EB=A7=88?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/db/migration/DDL_schema.sql | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/codeBoy_backend/src/main/resources/db/migration/DDL_schema.sql b/codeBoy_backend/src/main/resources/db/migration/DDL_schema.sql index b7379e2..80a21c3 100644 --- a/codeBoy_backend/src/main/resources/db/migration/DDL_schema.sql +++ b/codeBoy_backend/src/main/resources/db/migration/DDL_schema.sql @@ -49,6 +49,10 @@ COLLATE = utf8mb4_0900_ai_ci; CREATE TABLE IF NOT EXISTS `board_test`.`user_problem_set` ( `user_problem_set_id` BIGINT NOT NULL AUTO_INCREMENT, `member_id` BIGINT NOT NULL, + `category` VARCHAR(50) NOT NULL, + `comment_count` INT NOT NULL DEFAULT 0, + `title` VARCHAR(50) NOT NULL, + `created_at` TIMESTAMP NOT NULL DEFAULT NOW(), PRIMARY KEY (`user_problem_set_id`), INDEX `FK_member_TO_user_problem_set_1` (`member_id` ASC) VISIBLE, CONSTRAINT `FK_member_TO_user_problem_set_1` @@ -92,7 +96,7 @@ CREATE TABLE IF NOT EXISTS `board_test`.`problem` ( `choice_2` VARCHAR(255) NOT NULL, `choice_3` VARCHAR(255) NOT NULL, `choice_4` VARCHAR(255) NOT NULL, - `answer` VARCHAR(10) NOT NULL, + `answer` INT NOT NULL, `category` VARCHAR(50) NOT NULL, PRIMARY KEY (`problem_id`)) ENGINE = InnoDB @@ -185,13 +189,13 @@ ADD CONSTRAINT FK_quiz_room_TO_quiz_room_member_1 CREATE TABLE IF NOT EXISTS `board_test`.`user_problem` ( `user_problem_id` BIGINT NOT NULL AUTO_INCREMENT, `problem_description` VARCHAR(300) NOT NULL, - `category` VARCHAR(50) NOT NULL, + -- `category` VARCHAR(50) NOT NULL, `choice_1` VARCHAR(255) NOT NULL, `choice_2` VARCHAR(255) NOT NULL, `choice_3` VARCHAR(255) NOT NULL, `choice_4` VARCHAR(255) NOT NULL, - `answer` VARCHAR(10) NOT NULL, - `comment_count` INT NOT NULL DEFAULT 0, + `answer` INT NOT NULL, + -- `comment_count` INT NOT NULL DEFAULT 0, `user_problem_set_id` BIGINT NOT NULL, PRIMARY KEY (`user_problem_id`), INDEX `FK_user_problem_set_TO_user_problem_1` (`user_problem_set_id` ASC) VISIBLE, From 76ac0afd37b963a685fc3c970924c2f3f6942ac9 Mon Sep 17 00:00:00 2001 From: mingeung Date: Wed, 10 Dec 2025 15:10:35 +0900 Subject: [PATCH 55/61] =?UTF-8?q?fix=20:=20=ED=9A=8C=EC=9B=90=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=88=98=EC=A0=95=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20(=EC=A4=91=EB=B3=B5=20=EA=B2=80=EC=82=AC=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../codeboy/mvc/config/SecurityConfig.java | 2 +- .../mvc/controller/JoinController.java | 11 ++--- .../mvc/controller/MemberController.java | 46 +------------------ .../java/com/codeboy/mvc/jwt/LoginFilter.java | 15 +++--- .../dto/request/MemberUpdateRequest.java | 1 - .../mvc/model/dto/response/LoginResponse.java | 4 +- .../mvc/model/service/MemberServiceImpl.java | 41 +++++++++++------ .../main/resources/mappers/MemberMapper.xml | 7 ++- 8 files changed, 49 insertions(+), 78 deletions(-) diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java index 8a62da3..300ec84 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/config/SecurityConfig.java @@ -60,7 +60,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http, http .authorizeHttpRequests(auth -> auth - .requestMatchers("/", "/login", "/join", "/swagger-ui/**", + .requestMatchers("/", "/login", "/api/join", "/swagger-ui/**", "/v3/api-docs/**", "/api-docs/**", "/swagger-resources/**").permitAll() diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java index a8844f2..c830a4d 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/JoinController.java @@ -3,21 +3,20 @@ import com.codeboy.mvc.model.dto.request.JoinRequest; import com.codeboy.mvc.model.dto.response.ApiResponse; import com.codeboy.mvc.model.service.JoinService; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController @RequiredArgsConstructor +@RequestMapping("/api/join") +@Tag(name="join RESTful API", description = "회원가입 REST API") public class JoinController { private final JoinService joinService; - - @PostMapping("/join") + @PostMapping public ResponseEntity> adminP(@RequestBody JoinRequest joinRequest) { try { Long memberId = joinService.joinProcess(joinRequest); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java index d93880a..0523c78 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/controller/MemberController.java @@ -28,7 +28,7 @@ import java.util.NoSuchElementException; @RestController -@RequestMapping("/api") +@RequestMapping("/api/member") @Tag(name="Member RESTful API", description = "Member CRUD를 할 수 있는 REST API") public class MemberController { @@ -39,50 +39,8 @@ public MemberController(MemberService memberService) { this.memberService = memberService; } - - /** - * 내 정보 수정 - * PUT /api/members/me - * RequestBody: { nickname?, email?, password? } - * Response: - * 200 성공 시 수정된 정보 or 메시지 - * 400 잘못된 요청 - * 401 인증 실패 - */ - //회원정보 전체를 업데이트하지않고 일부만 수정하는 거라서 Put에서 Patch매핑으로 변경 - @PatchMapping("/members") - public ResponseEntity updateMe(@RequestBody MemberUpdateRequest request, @AuthenticationPrincipal CustomUserDetails loginUser) { - //파라미터로 memberId받아서 해당회원의 정보를 수정 - Long memberId = loginUser.getMemberId(); - Member member = memberService.getMemberById(memberId); - //회원을 못찾는 경우 ->존재하지 않는 memberId인경우 - if (member == null) { - return ResponseEntity - .status(HttpStatusCode.valueOf(401)) - .body("인증된 회원을 찾을 수 없습니다."); - } - - //닉네임과 이메일은 바꿀 수 있다고 가정. 필요하면 ID도..? - if (request.getNickname() != null) { - member.setNickname(request.getNickname()); - return ResponseEntity - .status(HttpStatusCode.valueOf(401)) - .body("닉네임이 없습니다.."); - } - if (request.getEmail() != null) { - member.setEmail(request.getEmail()); - return ResponseEntity - .status(HttpStatusCode.valueOf(401)) - .body("이메일이 없습니다"); - } - - return ResponseEntity - .status(HttpStatusCode.valueOf(200)) - .body("회원정보 수정 성공"); - } - //회원 조회 - @GetMapping("/members") + @GetMapping public ResponseEntity> getMemberInfo( @AuthenticationPrincipal CustomUserDetails loginUser) { Long memberId = loginUser.getMemberId(); try { diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java index b9b6ad9..fb40c5a 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/jwt/LoginFilter.java @@ -56,6 +56,8 @@ public Authentication attemptAuthentication(HttpServletRequest request, password = request.getParameter("password"); } + + UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); @@ -81,14 +83,15 @@ protected void successfulAuthentication(HttpServletRequest request, String role = principal.getAuthorities().iterator().next().getAuthority(); // 2) JWT 생성 - String token = jwtUtil.createJwt(username, role, 60 * 60 * 1000L); + String accessToken = jwtUtil.createJwt(username, role, 60 * 60 * 1000L); + String refreshToken = jwtUtil.createJwt(username, role, 7 * 24 * 60 * 60 * 1000L); + // 3) LoginResponse 생성 LoginResponse loginResponse = new LoginResponse( - token, - principal.getMemberId(), - principal.getUsername(), // 혹은 username - principal.getNickname() + accessToken, + refreshToken, + principal.getMemberId() ); // 4) ApiResponse 생성 @@ -114,7 +117,7 @@ protected void unsuccessfulAuthentication(HttpServletRequest request, System.out.println("login fail: " + failed.getMessage()); ApiResponse apiResponse = - ApiResponse.failure(HttpStatus.UNAUTHORIZED, "로그인에 실패했습니다."); // or failed.getMessage() + ApiResponse.failure(HttpStatus.UNAUTHORIZED, failed.getMessage()); // or failed.getMessage() response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("application/json;charset=UTF-8"); diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/MemberUpdateRequest.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/MemberUpdateRequest.java index c8b5e96..86afc67 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/MemberUpdateRequest.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/request/MemberUpdateRequest.java @@ -13,6 +13,5 @@ @Schema(description="유저 정보 수정 DTO") public class MemberUpdateRequest { private String nickname; - private String id; private String email; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/LoginResponse.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/LoginResponse.java index aa712fc..4b076ae 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/LoginResponse.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/dto/response/LoginResponse.java @@ -1,6 +1,7 @@ package com.codeboy.mvc.model.dto.response; // 예: com.codeboy.mvc.model.dto.response 패키지에 둔다 +import com.codeboy.mvc.model.dto.Member; import lombok.AllArgsConstructor; import lombok.Getter; @@ -8,7 +9,6 @@ @AllArgsConstructor public class LoginResponse { private String accessToken; + private String refreshToken; // 추가 private Long memberId; - private String id; - private String nickname; } diff --git a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java index a4ef431..7ff5bb0 100644 --- a/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java +++ b/codeBoy_backend/src/main/java/com/codeboy/mvc/model/service/MemberServiceImpl.java @@ -40,21 +40,27 @@ public void deactivateMember(Long memberId){ } - public void updateMember(Long memberId, MemberUpdateRequest memberUpdateRequest){ + public void updateMember(Long memberId, MemberUpdateRequest memberUpdateRequest) { isMemberExist(memberId); - //중복된 id, email이 있는지 검증 로직 - String id = memberUpdateRequest.getId(); + + // 현재 DB에 저장된 회원 정보 + Member current = memberDao.selectMemberById(memberId); + if (current == null) { + throw new IllegalStateException("회원 정보 수정 실패: 존재하지 않는 회원입니다. memberId: " + memberId); + } + String nickname = memberUpdateRequest.getNickname(); String email = memberUpdateRequest.getEmail(); - validateMemberUpdate(id, nickname, email); - int affectedRows = memberDao.updateMemberById(memberId, memberUpdateRequest); + // ✅ 내 현재 값과 비교해서, 실제로 바뀌는 필드만 중복체크 + validateMemberUpdate(current, nickname, email); + int affectedRows = memberDao.updateMemberById(memberId, memberUpdateRequest); if (affectedRows == 0) { throw new IllegalStateException("회원 정보 수정에 실패하였습니다. memberId: " + memberId); } + } - }; public boolean checkIdDuplicate(String id) { if (id == null) { throw new IllegalArgumentException("유효하지 않은 Id 입니다."); @@ -95,17 +101,24 @@ public void isMemberExist(Long memberId) { } // 최종 제출 시 전체 검증 - public void validateMemberUpdate(String id, String nickname, String email) { - if (memberDao.existsId(id)) { - throw new IllegalArgumentException("중복된 ID입니다."); - } - if (memberDao.existsNickname(nickname)) { - throw new IllegalArgumentException("중복된 닉네임입니다."); +// 현재 회원 정보 + 변경 요청값 기준 검증 + public void validateMemberUpdate(Member current, String nickname, String email) { + + // 닉네임 + if (nickname != null && !nickname.equals(current.getNickname())) { + if (memberDao.existsNickname(nickname)) { + throw new IllegalArgumentException("중복된 닉네임입니다."); + } } - if (memberDao.existsEmail(email)) { - throw new IllegalArgumentException("중복된 이메일입니다."); + + // 이메일 + if (email != null && !email.equals(current.getEmail())) { + if (memberDao.existsEmail(email)) { + throw new IllegalArgumentException("중복된 이메일입니다."); + } } } + // 로그인 public Member login(String id, String password) { diff --git a/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml index 7c0343b..b4437ae 100644 --- a/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml +++ b/codeBoy_backend/src/main/resources/mappers/MemberMapper.xml @@ -20,11 +20,9 @@ UPDATE member - nickname = #{update.nickname} - - - id = #{update.id} + nickname = #{update.nickname}, + email = #{update.email} @@ -32,6 +30,7 @@ WHERE member_id = #{memberId} +