diff --git a/backend/src/main/java/com/example/Piroin/project/domain/assignment/controller/AssignmentController.java b/backend/src/main/java/com/example/Piroin/project/domain/assignment/controller/AssignmentController.java index 7aa1920..fde00f1 100644 --- a/backend/src/main/java/com/example/Piroin/project/domain/assignment/controller/AssignmentController.java +++ b/backend/src/main/java/com/example/Piroin/project/domain/assignment/controller/AssignmentController.java @@ -2,7 +2,12 @@ import com.example.Piroin.project.domain.assignment.dto.CreateAssignmentRequest; import com.example.Piroin.project.domain.assignment.dto.CreateAssignmentResponse; +import com.example.Piroin.project.domain.assignment.dto.ModifyAssignmentRequest; +import com.example.Piroin.project.domain.assignment.dto.ModifyAssignmentResponse; +import com.example.Piroin.project.domain.assignment.entity.DeleteAssignmentResponse; import com.example.Piroin.project.domain.assignment.service.AssignmentService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; @@ -11,16 +16,43 @@ @RestController @RequiredArgsConstructor @RequestMapping("/assignments") +@Tag(name = "피로체크 과제 관리", description = "피로체크 과제 관리 API") public class AssignmentController { private final AssignmentService assignmentService; - @PostMapping + // 1. 과제 생성 + @Operation(summary = "과제 생성", description = "새로운 과제를 운영진이 입력하여 생성합니다.") + @PostMapping("/create") @ResponseStatus(HttpStatus.CREATED) public CreateAssignmentResponse createAssignment( @RequestBody CreateAssignmentRequest request ) { return assignmentService.createAssignment(request); } + + // 2. 과제 수정 + @Operation(summary = "과제 수정", description = "과제에 대한 과제명/주차/날짜를 운영진이 수정합니다.") + @PatchMapping("/modify/{assignmentId}") + @ResponseStatus(HttpStatus.OK) + public ModifyAssignmentResponse modifyAssignment( + @PathVariable Integer assignmentId, + @RequestBody ModifyAssignmentRequest request + ){ + return assignmentService.modifyAssignment(assignmentId, request); + } + + + // 3. 과제 삭제 + @Operation(summary = "과제 삭제", description = "운영진이 과제를 삭제합니다.") + @DeleteMapping("/{assignmentId}") + @ResponseStatus(HttpStatus.OK) + public DeleteAssignmentResponse deleteAssignment( + @PathVariable Integer assignmentId + ) { + + return assignmentService.deleteAssignment(assignmentId); + } + } diff --git a/backend/src/main/java/com/example/Piroin/project/domain/assignment/dto/CreateAssignmentRequest.java b/backend/src/main/java/com/example/Piroin/project/domain/assignment/dto/CreateAssignmentRequest.java index 5cf869c..a08d685 100644 --- a/backend/src/main/java/com/example/Piroin/project/domain/assignment/dto/CreateAssignmentRequest.java +++ b/backend/src/main/java/com/example/Piroin/project/domain/assignment/dto/CreateAssignmentRequest.java @@ -6,6 +6,7 @@ @Getter public class CreateAssignmentRequest { + private Integer assignmentId; private String title; diff --git a/backend/src/main/java/com/example/Piroin/project/domain/assignment/dto/ModifyAssignmentRequest.java b/backend/src/main/java/com/example/Piroin/project/domain/assignment/dto/ModifyAssignmentRequest.java new file mode 100644 index 0000000..0595cec --- /dev/null +++ b/backend/src/main/java/com/example/Piroin/project/domain/assignment/dto/ModifyAssignmentRequest.java @@ -0,0 +1,13 @@ +package com.example.Piroin.project.domain.assignment.dto; + +import lombok.Getter; +import java.time.LocalDate; + +@Getter +public class ModifyAssignmentRequest { + private String title; + + private String week; + + private LocalDate sessionDate; +} diff --git a/backend/src/main/java/com/example/Piroin/project/domain/assignment/dto/ModifyAssignmentResponse.java b/backend/src/main/java/com/example/Piroin/project/domain/assignment/dto/ModifyAssignmentResponse.java new file mode 100644 index 0000000..6825a46 --- /dev/null +++ b/backend/src/main/java/com/example/Piroin/project/domain/assignment/dto/ModifyAssignmentResponse.java @@ -0,0 +1,11 @@ +package com.example.Piroin.project.domain.assignment.dto; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ModifyAssignmentResponse { + private Integer assignmentId; +} diff --git a/backend/src/main/java/com/example/Piroin/project/domain/assignment/entity/Assignment.java b/backend/src/main/java/com/example/Piroin/project/domain/assignment/entity/Assignment.java index b439938..0145c62 100644 --- a/backend/src/main/java/com/example/Piroin/project/domain/assignment/entity/Assignment.java +++ b/backend/src/main/java/com/example/Piroin/project/domain/assignment/entity/Assignment.java @@ -25,4 +25,18 @@ public class Assignment { @Column(name = "session_date") private LocalDate sessionDate; // DATE 타입에 매칭 + public void update(String title, String week, LocalDate sessionDate) { + + if (title != null) { + this.title = title; + } + + if (week != null) { + this.week = week; + } + + if (sessionDate != null) { + this.sessionDate = sessionDate; + } + } } \ No newline at end of file diff --git a/backend/src/main/java/com/example/Piroin/project/domain/assignment/entity/DeleteAssignmentResponse.java b/backend/src/main/java/com/example/Piroin/project/domain/assignment/entity/DeleteAssignmentResponse.java new file mode 100644 index 0000000..837ea68 --- /dev/null +++ b/backend/src/main/java/com/example/Piroin/project/domain/assignment/entity/DeleteAssignmentResponse.java @@ -0,0 +1,11 @@ +package com.example.Piroin.project.domain.assignment.entity; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class DeleteAssignmentResponse { + + private Integer assignmentId; +} diff --git a/backend/src/main/java/com/example/Piroin/project/domain/assignment/exception/AssignmentException.java b/backend/src/main/java/com/example/Piroin/project/domain/assignment/exception/AssignmentException.java index 6738b3f..1b1dc69 100644 --- a/backend/src/main/java/com/example/Piroin/project/domain/assignment/exception/AssignmentException.java +++ b/backend/src/main/java/com/example/Piroin/project/domain/assignment/exception/AssignmentException.java @@ -1,7 +1,9 @@ package com.example.Piroin.project.domain.assignment.exception; +import com.example.Piroin.project.domain.assignment.exception.code.AssignmentErrorCode; + public class AssignmentException extends RuntimeException { - public AssignmentException(String message) { - super(message); + public AssignmentException(AssignmentErrorCode message) { + super(String.valueOf(message)); } } diff --git a/backend/src/main/java/com/example/Piroin/project/domain/assignment/exception/code/AssignmentErrorCode.java b/backend/src/main/java/com/example/Piroin/project/domain/assignment/exception/code/AssignmentErrorCode.java index 7e6f6c5..3221072 100644 --- a/backend/src/main/java/com/example/Piroin/project/domain/assignment/exception/code/AssignmentErrorCode.java +++ b/backend/src/main/java/com/example/Piroin/project/domain/assignment/exception/code/AssignmentErrorCode.java @@ -7,9 +7,20 @@ @Getter @RequiredArgsConstructor public enum AssignmentErrorCode { - ASSIGNMENT_CREATE_FAILED(HttpStatus.BAD_REQUEST, "ASSIGNMENT400", "과제 생성에 실패했습니다."); + + ASSIGNMENT_CREATE_FAILED( + HttpStatus.BAD_REQUEST, + "ASSIGNMENT400", + "과제 생성에 실패했습니다." + ), + + ASSIGNMENT_NOT_FOUND( + HttpStatus.NOT_FOUND, + "ASSIGNMENT404", + "해당 과제를 찾을 수 없습니다." + ); private final HttpStatus status; private final String code; private final String message; -} +} \ No newline at end of file diff --git a/backend/src/main/java/com/example/Piroin/project/domain/assignment/repository/AssignmentItemRepository.java b/backend/src/main/java/com/example/Piroin/project/domain/assignment/repository/AssignmentItemRepository.java index 17e0804..ec52d33 100644 --- a/backend/src/main/java/com/example/Piroin/project/domain/assignment/repository/AssignmentItemRepository.java +++ b/backend/src/main/java/com/example/Piroin/project/domain/assignment/repository/AssignmentItemRepository.java @@ -4,4 +4,8 @@ import org.springframework.data.jpa.repository.JpaRepository; public interface AssignmentItemRepository extends JpaRepository { + + void deleteAllByAssignmentId(Integer assignmentId); + + } diff --git a/backend/src/main/java/com/example/Piroin/project/domain/assignment/service/AssignmentService.java b/backend/src/main/java/com/example/Piroin/project/domain/assignment/service/AssignmentService.java index b220184..0f09a71 100644 --- a/backend/src/main/java/com/example/Piroin/project/domain/assignment/service/AssignmentService.java +++ b/backend/src/main/java/com/example/Piroin/project/domain/assignment/service/AssignmentService.java @@ -2,9 +2,14 @@ import com.example.Piroin.project.domain.assignment.dto.CreateAssignmentRequest; import com.example.Piroin.project.domain.assignment.dto.CreateAssignmentResponse; +import com.example.Piroin.project.domain.assignment.dto.ModifyAssignmentRequest; +import com.example.Piroin.project.domain.assignment.dto.ModifyAssignmentResponse; import com.example.Piroin.project.domain.assignment.entity.Assignment; import com.example.Piroin.project.domain.assignment.entity.AssignmentItem; +import com.example.Piroin.project.domain.assignment.entity.DeleteAssignmentResponse; import com.example.Piroin.project.domain.assignment.enums.AssignmentStatus; +import com.example.Piroin.project.domain.assignment.exception.AssignmentException; +import com.example.Piroin.project.domain.assignment.exception.code.AssignmentErrorCode; import com.example.Piroin.project.domain.assignment.repository.AssignmentItemRepository; import com.example.Piroin.project.domain.assignment.repository.AssignmentRepository; import com.example.Piroin.project.domain.user.entity.User; @@ -24,6 +29,7 @@ public class AssignmentService { private final AssignmentItemRepository assignmentItemRepository; private final UserRepository userRepository; + // 1. 과제 생성 public CreateAssignmentResponse createAssignment(CreateAssignmentRequest request) { Assignment assignment = Assignment.builder() @@ -48,4 +54,44 @@ public CreateAssignmentResponse createAssignment(CreateAssignmentRequest request return new CreateAssignmentResponse(assignment.getId()); } + + // 2. 과제 수정 + public ModifyAssignmentResponse modifyAssignment(Integer assignmentId, + ModifyAssignmentRequest request) { + + Assignment assignment = assignmentRepository.findById(assignmentId) + .orElseThrow(() -> new AssignmentException( + AssignmentErrorCode.ASSIGNMENT_NOT_FOUND + )); + + assignment.update( + request.getTitle(), + request.getWeek(), + request.getSessionDate() + ); + + assignmentRepository.save(assignment); + + return new ModifyAssignmentResponse(assignment.getId()); + } + + // 3. 과제 삭제 + public DeleteAssignmentResponse deleteAssignment(Integer assignmentId) { + + Assignment assignment = assignmentRepository.findById(assignmentId) + .orElseThrow(() -> + new AssignmentException( + AssignmentErrorCode.ASSIGNMENT_NOT_FOUND + ) + ); + + // assignment_item 먼저 삭제 + assignmentItemRepository.deleteAllByAssignmentId(assignmentId); + + // assignment 삭제 + assignmentRepository.delete(assignment); + + return new DeleteAssignmentResponse(assignmentId); + } + } diff --git a/backend/src/main/java/com/example/Piroin/project/domain/attendance/controller/AttendanceController.java b/backend/src/main/java/com/example/Piroin/project/domain/attendance/controller/AttendanceController.java index 477476a..5ff0015 100644 --- a/backend/src/main/java/com/example/Piroin/project/domain/attendance/controller/AttendanceController.java +++ b/backend/src/main/java/com/example/Piroin/project/domain/attendance/controller/AttendanceController.java @@ -13,6 +13,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; //import com.example.Piroin.project.global.util.SecurityUtil; +import org.springframework.security.core.Authentication; import org.springframework.security.core.annotation.AuthenticationPrincipal; import lombok.RequiredArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; @@ -31,29 +32,22 @@ public class AttendanceController { // 1. 출석코드 비교 - @Operation(summary = "출석 체크", description = "출석 코드를 입력하여 출석을 체크합니다.") - @ApiResponses({ - @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "출석 성공 또는 이미 출석 완료"), - @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "잘못된 출석 코드 또는 출석 체크 진행중이 아님") - }) @PostMapping("/mark") public ApiResponse markAttendance( - @io.swagger.v3.oas.annotations.parameters.RequestBody( - description = "출석 체크 요청", - required = true, - content = @Content(schema = @Schema(implementation = MarkAttendanceReq.class)) - ) @RequestBody MarkAttendanceReq req, - @AuthenticationPrincipal Integer userId + Authentication authentication ) { - // [수정] 서비스 메서드 스펙 변경에 맞춰 req.getStudySessionId()를 제거했습니다. + + Long userId = Long.valueOf(authentication.getName()); + AttendanceMarkResponse response = attendanceService.markAttendance( - Long.valueOf(userId), + userId, req.getCode() ); - boolean isSuccess = "SUCCESS".equals(response.getStatusCode()) || - "ALREADY_MARKED".equals(response.getStatusCode()); + boolean isSuccess = + "SUCCESS".equals(response.getStatusCode()) || + "ALREADY_MARKED".equals(response.getStatusCode()); if (isSuccess) { return ApiResponse.success(response);