Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package backend.pirocheck.Assignment.controller;

import backend.pirocheck.Assignment.dto.request.AssignmentCreateReq;
import backend.pirocheck.Assignment.dto.request.AssignmentItemCreateReq;
import backend.pirocheck.Assignment.dto.request.AssignmentUpdateReq;
import backend.pirocheck.Assignment.dto.response.AssignmentWeekRes;
import backend.pirocheck.Assignment.entity.AssignmentStatus;
import backend.pirocheck.Assignment.service.AssignmentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
@Tag(name = "과제관리", description = "과제 관련 API")
public class AssignmentController {

private final AssignmentService assignmentService;

// 과제 결과 확인 API
// 과제 주차별, 요일별 그룹화 JSON
@Operation(summary = "학생별 과제 결과 확인", description = "관리자가 채점한 과제의 결과를 학생들이 확인합니다.")
@ApiResponses(
value = {
@ApiResponse(responseCode = "200", description = "사용자별 과제 조회에 성공하였습니다."),
@ApiResponse(responseCode = "400", description = "잘못된 요청입니다.")
}
)
@GetMapping("/assignment/{userId}")
public List<AssignmentWeekRes> getGroupedAssignments(
@Parameter(description = "사용자 ID", example = "1")
@PathVariable Long userId
) {
return assignmentService.search(userId);
}

// 과제 생성 API
@Operation(summary = "과제 생성 API", description = "관리자가 과제를 생성합니다.")
@ApiResponses(
value = {
@ApiResponse(responseCode = "200", description = "과제 생성에 성공하였습니다."),
@ApiResponse(responseCode = "400", description = "잘못된 요청입니다.")
}
)
@PostMapping("/admin/assignment/signup")
public String signupAssignment(
@Valid
@RequestBody AssignmentCreateReq assignmentCreateReq
) {
return assignmentService.createAssignment(assignmentCreateReq);
}

// 과제 삭제 API
@Operation(summary = "과제 삭제 API", description = "관리자가 과제를 삭제합니다.")
@ApiResponses(
value = {
@ApiResponse(responseCode = "200", description = "과제 삭제에 성공하였습니다."),
@ApiResponse(responseCode = "400", description = "잘못된 요청입니다.")
}
)
@DeleteMapping("/admin/assignment/{assignmentId}")
public String deleteAssignment(
@Parameter(description = "과제 ID", example = "1")
@PathVariable Long assignmentId
) {
return assignmentService.deleteAssignment(assignmentId);
}

// 과제 수정 API
@Operation(summary = "과제 수정 API", description = "관리자가 과제의 잘못된 부분을 수정합니다.")
@ApiResponses(
value = {
@ApiResponse(responseCode = "200", description = "과제 수정에 성공하였습니다."),
@ApiResponse(responseCode = "400", description = "잘못된 요청입니다.")
}
)
@PutMapping("/admin/assignment/{assignmentId}")
public String updateAssignment(
@Parameter(description = "과제 ID", example = "1")
@PathVariable("assignmentId") Long assignmentId,
@RequestBody AssignmentUpdateReq assignmentUpdateReq
) {
return assignmentService.updateAssignment(assignmentId, assignmentUpdateReq);
}

// 사용자별 과제 제출 결과 생성 API
@Operation(summary = "관리자 과제 채점 API", description = "관리자가 사용자들의 과제를 채점한 결과 저장합니다.")
@ApiResponses(
value = {
@ApiResponse(responseCode = "200", description = "사용자의 과제 채점 결과 저장에 성공하였습니다."),
@ApiResponse(responseCode = "400", description = "잘못된 요청입니다.")
}
)
@PostMapping("/admin/users/{userId}/assignments/{assignmentId}/submission")
public AssignmentStatus submissionAssignment(
@Parameter(description = "사용자 ID", example = "1")
@PathVariable Long userId,
@Parameter(description = "과제 ID", example = "1")
@PathVariable Long assignmentId,
@RequestBody AssignmentItemCreateReq req
) {
return assignmentService.createAssignmentItem(userId, assignmentId, req);
}

// 사용자별 과제 제출 여부 수정 API
@Operation(summary = "관리자 과제 채점 내용 수정 API", description = "관리자가 사용자의 과제 결과를 수정하여 저장합니다.")
@ApiResponses(
value = {
@ApiResponse(responseCode = "200", description = "사용자 과제 채점 결과 수정에 성공하였습니다."),
@ApiResponse(responseCode = "400", description = "잘못된 요청입니다.")
}
)
@PutMapping("/admin/users/{userId}/assignments/{assignmentId}/submission")
public String updateSubmission(
@Parameter(description = "사용자 ID", example = "1")
@PathVariable Long userId,
@Parameter(description = "과제 ID", example = "1")
@PathVariable Long assignmentId
) {
return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package backend.pirocheck.Assignment.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class AssignmentCreateReq {

@Schema(description = "과제 주제", example = "Git/HTML/CSS")
@NotNull(message = "과제 주제는 필수입니다.")
private String subject;

@Schema(description = "과제명", example = "제로초 인강")
@NotNull(message = "과제명은 필수입니다.")
private String assignmentName;

@Schema(description = "주차", example = "1")
@Positive
private Long week;

@Schema(description = "요일", example = "화")
@NotBlank(message = "요일을 입력해주세요.")
private String day;

@Schema(description = "해당 일자 과제 numbering", example = "1")
private Long orderNumber;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package backend.pirocheck.Assignment.dto.request;

import backend.pirocheck.Assignment.entity.AssignmentStatus;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Pattern;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class AssignmentItemCreateReq {

private Long assignmentId;

private Long userId;

@Pattern(regexp = "SUCCESS/INSUFFICIENT/FAILURE", message = "status는 SUCCESS, INSUFFICIENT 혹은 FAILURE 여야 합니다.")
@Schema(description = "과제 결과", example = "SUCCESS")
private AssignmentStatus status;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package backend.pirocheck.Assignment.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class AssignmentUpdateReq {

@Schema(description = "과제 주제", example = "Git/HTML/CSS")
@NotNull(message = "과제 주제는 필수입니다.")
private String subject;

@Schema(description = "과제명", example = "제로초 인강")
@NotNull(message = "과제명은 필수입니다.")
private String assignmentName;

@Schema(description = "주차", example = "1")
@Positive
private Long week;

@Schema(description = "요일", example = "화")
@NotBlank(message = "요일을 입력해주세요.")
private String day;

@Schema(description = "해당 일자 과제 numbering", example = "1")
private Long orderNumber;

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package backend.pirocheck.assignment.dto.response;
package backend.pirocheck.Assignment.dto.response;

import lombok.AllArgsConstructor;
import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package backend.pirocheck.assignment.dto.response;
package backend.pirocheck.Assignment.dto.response;

import backend.pirocheck.assignment.entity.AssignmentStatus;
import backend.pirocheck.Assignment.entity.AssignmentStatus;
import lombok.AllArgsConstructor;
import lombok.Getter;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package backend.pirocheck.assignment.dto.response;
package backend.pirocheck.Assignment.dto.response;

import backend.pirocheck.assignment.entity.AssignmentStatus;
import backend.pirocheck.Assignment.entity.AssignmentStatus;
import lombok.AllArgsConstructor;
import lombok.Getter;

Expand All @@ -11,7 +11,7 @@ public class AssignmentRes {
// private Long userId;
private String assignmentName;
private Long week;
private Long section;
private String day;
private Long orderNumber;
private AssignmentStatus submitted;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package backend.pirocheck.assignment.dto.response;
package backend.pirocheck.Assignment.dto.response;

import lombok.AllArgsConstructor;
import lombok.Getter;
Expand All @@ -9,6 +9,6 @@
@AllArgsConstructor
public class AssignmentWeekRes {
private Long week;
private String title; // 각 주차 주제 (e.g, Git / HTML / CSS)
private String subject; // 각 주차 주제 (e.g, Git / HTML / CSS)
private List<AssignmentDayRes> days;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package backend.pirocheck.Assignment.entity;

import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.persistence.*;
import lombok.*;

import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@Builder(access = AccessLevel.PRIVATE)
@NoArgsConstructor
@AllArgsConstructor
@Tag(name = "과제 관리", description = "과제 관련 API")
public class Assignment {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

// 전체 주제
private String subject;

// 과제명
private String assignmentName;

// 주차
private Long week;

// 요일
private String day;

// 과제 번호
private Long orderNumber;

// AssignmentItem 입장에서 "assignment" 필드의 외래 키를 가진 주인
// assignment를 참조하는 assignmentitem 컬랙션을 가짐
@OneToMany(mappedBy = "assignment", cascade = CascadeType.ALL, orphanRemoval = true)
private List<AssignmentItem> assignments = new ArrayList<>();

// 연관관계 편의 메서드 (양방향 시 자주 사용)
public void addAssignmentItem(AssignmentItem assignmentItem) {
this.assignments.add(assignmentItem);
assignmentItem.setAssignment(this);
}

// 관리자가 생성
public static Assignment create(String subject, String assignmentName, Long week, String day, Long orderNumber) {
return Assignment.builder()
.subject(subject)
.assignmentName(assignmentName)
.week(week)
.day(day)
.orderNumber(orderNumber)
.build();
}

// 과제 내용 업데이트
public void update(String subject, String assignmentName, Long week, String day, Long orderNumber) {
this.subject = subject;
this.assignmentName = assignmentName;
this.week = week;
this.day = day;
this.orderNumber = orderNumber;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package backend.pirocheck.Assignment.entity;

import backend.pirocheck.User.entity.User;
import jakarta.persistence.*;
import lombok.*;

@Entity
@Getter
@Setter
@Builder(access = AccessLevel.PRIVATE)
@AllArgsConstructor
@NoArgsConstructor
public class AssignmentItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // 유저별 과제 정보를 저장하는 ID

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "assignment_id")
private Assignment assignment;

// 과제 결과
@Enumerated(EnumType.STRING)
@Column(length = 100)
private AssignmentStatus submitted; // 수강생의 과제 제출여부

public static AssignmentItem create(User user, Assignment assignment, AssignmentStatus submitted) {
return AssignmentItem.builder()
.assignment(assignment)
.user(user)
.submitted(submitted)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package backend.pirocheck.assignment.entity;
package backend.pirocheck.Assignment.entity;

public enum AssignmentStatus {
SUCCESS, INSUFFICIENT, FAILURE;
Expand Down
Loading