diff --git a/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmission.java b/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmission.java index 08b7c875..cada5e9f 100644 --- a/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmission.java +++ b/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmission.java @@ -63,6 +63,11 @@ public class AssignmentSubmission { private Double grade; private String feedback; + @Column(columnDefinition = "text") + private String aiSummary; + + private Integer qualityScore; + private String comment; private Long assignmentid; diff --git a/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmissionAPIController.java b/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmissionAPIController.java index d49653bc..172bdc1b 100644 --- a/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmissionAPIController.java +++ b/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmissionAPIController.java @@ -300,10 +300,12 @@ public ResponseEntity updateSubmission( submission.setComment(comment == null ? "" : comment); submission.setIsLate(Boolean.TRUE.equals(isLate)); - // Only clear grade/feedback when the submission content actually changed + // Only clear grade/feedback/AI summary/quality score when the content actually changed if (contentChanged) { submission.setGrade(null); submission.setFeedback(null); + submission.setAiSummary(null); + submission.setQualityScore(null); } AssignmentSubmission savedSubmission = submissionRepo.save(submission); @@ -350,6 +352,45 @@ public ResponseEntity gradeSubmission( return ResponseEntity.ok(new AssignmentSubmissionReturnDto(savedSubmission)); } + /** + * Persist an AI-generated summary for a submission (admin/teacher only). + * + * @param submissionId the ID of the submission being summarized + * @param summary the generated summary text + * @return a ResponseEntity indicating success or an error if the submission is not found + */ + @PostMapping("/summary/{submissionId}") + @Transactional + public ResponseEntity saveSubmissionSummary( + @PathVariable Long submissionId, + @AuthenticationPrincipal UserDetails userDetails, + @RequestParam String summary, + @RequestParam(required = false) Integer qualityScore + ) { + Person currentUser = getAuthenticatedPerson(userDetails); + if (currentUser == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(Map.of("error", "Authentication required")); + } + if (!canGradeOrDeleteSubmission(currentUser)) { + return ResponseEntity.status(HttpStatus.FORBIDDEN) + .body(Map.of("error", "Admin or teacher access required")); + } + + AssignmentSubmission submission = submissionRepo.findById(submissionId).orElse(null); + if (submission == null) { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", "Submission not found")); + } + + submission.setAiSummary(summary); + if (qualityScore != null && qualityScore >= 1 && qualityScore <= 5) { + submission.setQualityScore(qualityScore); + } + AssignmentSubmission savedSubmission = submissionRepo.save(submission); + return ResponseEntity.ok(new AssignmentSubmissionReturnDto(savedSubmission)); + } + /** * Delete an existing assignment submission. * diff --git a/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmissionReturnDto.java b/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmissionReturnDto.java index a3e02107..d7177d39 100644 --- a/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmissionReturnDto.java +++ b/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmissionReturnDto.java @@ -21,6 +21,8 @@ public class AssignmentSubmissionReturnDto { public Double grade; public String feedback; public Boolean isLate; + public String aiSummary; + public Integer qualityScore; public AssignmentSubmissionReturnDto(AssignmentSubmission submission) { this.id = submission.getId(); @@ -32,5 +34,7 @@ public AssignmentSubmissionReturnDto(AssignmentSubmission submission) { this.grade = submission.getGrade(); this.feedback = submission.getFeedback(); this.isLate = submission.getIsLate(); + this.aiSummary = submission.getAiSummary(); + this.qualityScore = submission.getQualityScore(); } } \ No newline at end of file diff --git a/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmissionViewController.java b/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmissionViewController.java index da726930..3b34cf1c 100644 --- a/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmissionViewController.java +++ b/src/main/java/com/open/spring/mvc/assignments/AssignmentSubmissionViewController.java @@ -153,6 +153,8 @@ public static class SubmissionListDTO { private String feedback; private Boolean isLate; private Boolean isGroup; + private String aiSummary; + private Integer qualityScore; // Private constructor for factory use private SubmissionListDTO() {} @@ -211,14 +213,18 @@ public static SubmissionListDTO from(AssignmentSubmission submission) { dto.grade = submission.getGrade(); dto.feedback = submission.getFeedback() != null ? submission.getFeedback() : ""; dto.isLate = submission.getIsLate() != null ? submission.getIsLate() : false; + dto.aiSummary = submission.getAiSummary(); + dto.qualityScore = submission.getQualityScore(); } catch (Exception e) { dto.content = null; dto.comment = ""; dto.grade = null; dto.feedback = ""; dto.isLate = false; + dto.aiSummary = null; + dto.qualityScore = null; } - + return dto; } @@ -239,6 +245,8 @@ public static SubmissionListDTO createFallback(AssignmentSubmission submission) dto.grade = null; dto.feedback = ""; dto.isLate = false; + dto.aiSummary = null; + dto.qualityScore = null; } catch (Exception e) { logger.error("Error in SubmissionListDTO.createFallback()", e); } @@ -257,6 +265,8 @@ public static SubmissionListDTO createFallback(AssignmentSubmission submission) public String getFeedback() { return feedback; } public Boolean getIsLate() { return isLate; } public Boolean getIsGroup() { return isGroup; } + public String getAiSummary() { return aiSummary; } + public Integer getQualityScore() { return qualityScore; } } /**