From eed5a0dd569de20c5d85f5b569b8a3aeec286d53 Mon Sep 17 00:00:00 2001 From: aarbit Date: Fri, 15 May 2026 13:40:25 -0500 Subject: [PATCH] Implements get photos for an item --- README.md | 1 - .../controller/ItemController.kt | 2 +- .../controller/TeamController.kt | 5 +++-- .../scavengerhuntapi/service/PhotoService.kt | 18 ++++++++++++++++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8cc6c5c..bb707ad 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,5 @@ All endpoints except `/signup` and `/login` require a JWT bearer token. ## TODO -- `GET /hunt/{huntId}/team/{teamId}/item/{itemId}/photo` — list photos for a team's item - `GET /lead/hunt/{huntId}/team` — leaderboard: teams with scores for a hunt - `GET /lead/hunt/{huntId}/hunter` — leaderboard: hunters with scores for a hunt diff --git a/src/main/kotlin/net/halfbinary/scavengerhuntapi/controller/ItemController.kt b/src/main/kotlin/net/halfbinary/scavengerhuntapi/controller/ItemController.kt index 431a1a8..5eabe68 100644 --- a/src/main/kotlin/net/halfbinary/scavengerhuntapi/controller/ItemController.kt +++ b/src/main/kotlin/net/halfbinary/scavengerhuntapi/controller/ItemController.kt @@ -30,7 +30,7 @@ class ItemController(private val huntService: HuntService) { @GetMapping("/{itemId}") fun getItem(@PathVariable huntId: HuntId, @PathVariable itemId: ItemId): ResponseEntity { - TODO("Get detailed information about the specified Item for the specified Hunt") + TODO("Maybe not needed: Get detailed information about the specified Item for the specified Hunt") } @PreAuthorize("hasRole('ADMIN')") diff --git a/src/main/kotlin/net/halfbinary/scavengerhuntapi/controller/TeamController.kt b/src/main/kotlin/net/halfbinary/scavengerhuntapi/controller/TeamController.kt index 7f46d6d..bb1ca5d 100644 --- a/src/main/kotlin/net/halfbinary/scavengerhuntapi/controller/TeamController.kt +++ b/src/main/kotlin/net/halfbinary/scavengerhuntapi/controller/TeamController.kt @@ -61,8 +61,9 @@ class TeamController(private val teamService: TeamService, private val photoServ @Operation(summary = "Get list of photo information for the specified Team, Hunt, and Item") fun getItemPhotos(@PathVariable huntId: HuntId, @PathVariable teamId: TeamId, - @PathVariable itemId: ItemId): ResponseEntity> { - TODO("Get list of photo information for the specified Team, Hunt, and Item") + @PathVariable itemId: ItemId, + authentication: Authentication): ResponseEntity> { + return ResponseEntity.ok(photoService.getItemPhotos(huntId, teamId, itemId, authentication.name)) } @PatchMapping("/{teamId}/item/{itemId}/photo/{photoId}") diff --git a/src/main/kotlin/net/halfbinary/scavengerhuntapi/service/PhotoService.kt b/src/main/kotlin/net/halfbinary/scavengerhuntapi/service/PhotoService.kt index 93b530a..612515a 100644 --- a/src/main/kotlin/net/halfbinary/scavengerhuntapi/service/PhotoService.kt +++ b/src/main/kotlin/net/halfbinary/scavengerhuntapi/service/PhotoService.kt @@ -157,6 +157,24 @@ class PhotoService( photoRepository.save(photoRecord.copy(status = PhotoStatus.REMOVED, statusChangeDateTime = LocalDateTime.now())) } + fun getItemPhotos(huntId: HuntId, teamId: TeamId, itemId: ItemId, email: String): List { + val requestingHunter = hunterService.getHunterByEmail(email) + + if (!requestingHunter.isAdmin) { + val team = try { + teamService.getTeamForHunterInHunt(huntId, email) + } catch (_: NotFoundException) { + throw ForbiddenException() + } + if (team.id != teamId) throw ForbiddenException() + } + + val teamHunterIds = teamService.getHunterIdsForTeam(teamId) + return photoRepository.findByHuntIdAndItemId(huntId, itemId) + .filter { it.hunterId in teamHunterIds && it.status != PhotoStatus.REMOVED } + .map { it.toDomain().toResponse(hunterService.getHunterById(it.hunterId)) } + } + fun updatePhotoStatus(photoId: PhotoId, status: PhotoStatus) { val record = photoRepository.findByIdOrNull(photoId) ?: throw NotFoundException(PHOTO_NOT_FOUND)