Skip to content

feat: image assessment upload #82

Merged
merged 2 commits into from
Apr 30, 2026
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Expand Up @@ -4,6 +4,7 @@ import edu.ntnu.idi.idatt.backend.game.tasks.application.TaskService
import edu.ntnu.idi.idatt.backend.iam.security.CurrentUser
import jakarta.validation.Valid
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.GetMapping
Expand All @@ -16,6 +17,7 @@ import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.MultipartFile

/**
* REST API for listing, authoring, publishing, and deleting classroom tasks.
Expand Down Expand Up @@ -71,6 +73,17 @@ class TaskController(
@AuthenticationPrincipal currentUser: CurrentUser,
): TaskResponse = taskService.createTask(request.toCommand(classroomId, currentUser)).toResponse()

/**
* Uploads an image for teacher-authored task content inside one classroom.
*/
@PostMapping("/upload", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
@ResponseStatus(HttpStatus.CREATED)
fun uploadTaskMedia(
@PathVariable classroomId: Long,
@RequestParam("file") file: MultipartFile,
@AuthenticationPrincipal currentUser: CurrentUser,
): Map<String, String> = mapOf("url" to taskService.uploadTaskMedia(currentUser, classroomId, file))

/**
* Replaces the editable contents of an existing task.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ import edu.ntnu.idi.idatt.backend.iam.application.CurrentUserResolver
import edu.ntnu.idi.idatt.backend.iam.domain.User
import edu.ntnu.idi.idatt.backend.iam.domain.UserRole
import edu.ntnu.idi.idatt.backend.iam.security.CurrentUser
import edu.ntnu.idi.idatt.backend.upload.application.FileStorageService
import org.springframework.dao.DataIntegrityViolationException
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.multipart.MultipartFile
import org.springframework.web.server.ResponseStatusException

/**
Expand All @@ -39,6 +41,7 @@ class TaskService(
private val currentUserResolver: CurrentUserResolver,
private val pupilStopProgressService: PupilStopProgressService,
private val gameAccessContextResolver: GameAccessContextResolver,
private val fileStorageService: FileStorageService,
) {
/**
* Lists tasks for a classroom, optionally filtered by stop.
Expand Down Expand Up @@ -236,6 +239,21 @@ class TaskService(
taskRepository.delete(task)
}

/**
* Uploads one image for task authoring inside the given classroom.
*
* The returned URL is intended to be written into a task item's mediaUrl.
*/
@Transactional(readOnly = true)
fun uploadTaskMedia(
currentUser: CurrentUser,
classroomId: Long,
file: MultipartFile,
): String {
requireOwnedClassroom(currentUser.subject, classroomId)
return fileStorageService.store(file, "tasks/classroom-$classroomId")
}

/**
* Submits answers for all published tasks at a stop.
*
Expand Down