Adds user level hunt endpoints
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
package net.halfbinary.scavengerhuntapi.controller
|
package net.halfbinary.scavengerhuntapi.controller
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag
|
||||||
import jakarta.validation.Valid
|
import jakarta.validation.Valid
|
||||||
import net.halfbinary.scavengerhuntapi.model.HuntId
|
import net.halfbinary.scavengerhuntapi.model.HuntId
|
||||||
import net.halfbinary.scavengerhuntapi.model.HunterId
|
import net.halfbinary.scavengerhuntapi.model.HunterId
|
||||||
@@ -9,32 +11,61 @@ import net.halfbinary.scavengerhuntapi.model.request.HuntCreateRequest
|
|||||||
import net.halfbinary.scavengerhuntapi.model.request.HuntStatus
|
import net.halfbinary.scavengerhuntapi.model.request.HuntStatus
|
||||||
import net.halfbinary.scavengerhuntapi.model.response.HuntResponse
|
import net.halfbinary.scavengerhuntapi.model.response.HuntResponse
|
||||||
import net.halfbinary.scavengerhuntapi.service.HuntService
|
import net.halfbinary.scavengerhuntapi.service.HuntService
|
||||||
|
import net.halfbinary.scavengerhuntapi.service.HunterService
|
||||||
import org.springframework.http.ResponseEntity
|
import org.springframework.http.ResponseEntity
|
||||||
import org.springframework.security.access.prepost.PreAuthorize
|
import org.springframework.security.access.prepost.PreAuthorize
|
||||||
|
import org.springframework.security.core.Authentication
|
||||||
import org.springframework.web.bind.annotation.*
|
import org.springframework.web.bind.annotation.*
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("hunt")
|
@RequestMapping("hunt")
|
||||||
class HuntController(private val huntService: HuntService) {
|
class HuntController(private val huntService: HuntService, private val hunterService: HunterService) {
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
|
@Operation(summary = "Gets the specified hunt information")
|
||||||
fun getHunt(@PathVariable("id") huntId: HuntId): ResponseEntity<HuntResponse> {
|
fun getHunt(@PathVariable("id") huntId: HuntId): ResponseEntity<HuntResponse> {
|
||||||
return ResponseEntity.ok(huntService.getHunt(huntId).toResponse())
|
return ResponseEntity.ok(huntService.getHunt(huntId).toResponse())
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("hasRole('ADMIN')")
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
@Tag(name = "Admin")
|
||||||
@GetMapping()
|
@GetMapping()
|
||||||
|
@Operation(summary = "Gets all Hunts")
|
||||||
fun getAllHunts(@RequestParam status: HuntStatus?): ResponseEntity<List<HuntResponse>> {
|
fun getAllHunts(@RequestParam status: HuntStatus?): ResponseEntity<List<HuntResponse>> {
|
||||||
return ResponseEntity.ok(huntService.getAllHunts(status).map { it.toResponse() })
|
return ResponseEntity.ok(huntService.getAllHunts(status).map { it.toResponse() })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/ongoing")
|
||||||
|
@Operation(summary = "Gets list of all currently running Hunts (filtered by the calling hunter)")
|
||||||
|
fun getOngoingHunts(authentication: Authentication, @RequestParam status: HuntStatus?): ResponseEntity<List<HuntResponse>> {
|
||||||
|
val email = authentication.name
|
||||||
|
val isAdmin = hunterService.getHunterByEmail(email).isAdmin
|
||||||
|
return if(isAdmin) {
|
||||||
|
ResponseEntity.ok(huntService.getAllHunts(HuntStatus.ONGOING).map { it.toResponse() })
|
||||||
|
} else {
|
||||||
|
ResponseEntity.ok(huntService.getHuntsByEmail(email, status).map { it.toResponse() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/unstarted")
|
||||||
|
@Operation(summary = "Gets list of all upcoming Hunts")
|
||||||
|
fun getUnstartedHunts(): ResponseEntity<List<HuntResponse>> {
|
||||||
|
return ResponseEntity.ok(huntService.getAllHunts(HuntStatus.UNSTARTED).map { it.toResponse() })
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
@Tag(name = "Admin")
|
||||||
@PostMapping()
|
@PostMapping()
|
||||||
|
@Operation(summary = "Creates a new Hunt")
|
||||||
fun createHunt(@Valid @RequestBody huntRequest: HuntCreateRequest): ResponseEntity<HuntResponse> {
|
fun createHunt(@Valid @RequestBody huntRequest: HuntCreateRequest): ResponseEntity<HuntResponse> {
|
||||||
return ResponseEntity.ok(huntService.createHunt(huntRequest.toDomain()).toResponse())
|
return ResponseEntity.ok(huntService.createHunt(huntRequest.toDomain()).toResponse())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
@Tag(name = "Admin")
|
||||||
@GetMapping("/hunter/{hunterId}")
|
@GetMapping("/hunter/{hunterId}")
|
||||||
fun getHuntsByHunter(@PathVariable("hunterId") hunterId: HunterId): ResponseEntity<List<HuntResponse>> {
|
@Operation(summary = "Lists all Hunts for specified Hunter")
|
||||||
|
fun getHuntsByHunter(@PathVariable hunterId: HunterId): ResponseEntity<List<HuntResponse>> {
|
||||||
return ResponseEntity.ok(huntService.getHuntsByHunter(hunterId).map { it.toResponse() })
|
return ResponseEntity.ok(huntService.getHuntsByHunter(hunterId).map { it.toResponse() })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package net.halfbinary.scavengerhuntapi.repository
|
|||||||
|
|
||||||
import net.halfbinary.scavengerhuntapi.model.HuntId
|
import net.halfbinary.scavengerhuntapi.model.HuntId
|
||||||
import net.halfbinary.scavengerhuntapi.model.HunterId
|
import net.halfbinary.scavengerhuntapi.model.HunterId
|
||||||
|
import net.halfbinary.scavengerhuntapi.model.TeamId
|
||||||
import net.halfbinary.scavengerhuntapi.model.record.HuntRecord
|
import net.halfbinary.scavengerhuntapi.model.record.HuntRecord
|
||||||
import org.springframework.data.jpa.repository.JpaRepository
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
import org.springframework.data.jpa.repository.Query
|
import org.springframework.data.jpa.repository.Query
|
||||||
@@ -23,6 +24,17 @@ interface HuntRepository : JpaRepository<HuntRecord, HuntId> {
|
|||||||
""", nativeQuery = true)
|
""", nativeQuery = true)
|
||||||
fun findAllOngoingByHunter(hunterId: HunterId): List<HuntRecord>
|
fun findAllOngoingByHunter(hunterId: HunterId): List<HuntRecord>
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
SELECT h.*
|
||||||
|
FROM hunter u
|
||||||
|
INNER JOIN hunter_team ht ON u.id = ht.hunter_id
|
||||||
|
INNER JOIN team t ON ht.team_id = t.id
|
||||||
|
INNER JOIN team_hunt th ON t.id = th.team_id
|
||||||
|
INNER JOIN hunt h ON th.hunt_id = h.id
|
||||||
|
WHERE u.email = :email
|
||||||
|
""", nativeQuery = true)
|
||||||
|
fun findHuntsByEmail(email: String): List<HuntRecord>
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT h.*
|
SELECT h.*
|
||||||
FROM hunt h
|
FROM hunt h
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import net.halfbinary.scavengerhuntapi.model.request.HuntStatus
|
|||||||
import net.halfbinary.scavengerhuntapi.repository.HuntRepository
|
import net.halfbinary.scavengerhuntapi.repository.HuntRepository
|
||||||
import org.springframework.data.repository.findByIdOrNull
|
import org.springframework.data.repository.findByIdOrNull
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class HuntService(private val huntRepository: HuntRepository) {
|
class HuntService(private val huntRepository: HuntRepository) {
|
||||||
@@ -30,6 +31,27 @@ class HuntService(private val huntRepository: HuntRepository) {
|
|||||||
return huntRepository.findAllOngoingByHunter(hunterId).map { it.toDomain() }
|
return huntRepository.findAllOngoingByHunter(hunterId).map { it.toDomain() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getHuntsByEmail(email: String, status: HuntStatus?): List<Hunt> {
|
||||||
|
val allHunts = huntRepository.findHuntsByEmail(email)
|
||||||
|
val filteredHunts = when (status) {
|
||||||
|
HuntStatus.ONGOING -> {
|
||||||
|
allHunts
|
||||||
|
.filter { !it.isTerminated && it.startDateTime < LocalDateTime.now() && it.endDateTime > LocalDateTime.now() }
|
||||||
|
.toList()
|
||||||
|
}
|
||||||
|
HuntStatus.CLOSED -> {
|
||||||
|
allHunts
|
||||||
|
.filter { it.isTerminated || it.endDateTime < LocalDateTime.now() }
|
||||||
|
}
|
||||||
|
HuntStatus.UNSTARTED -> {
|
||||||
|
allHunts
|
||||||
|
.filter { !it.isTerminated && it.startDateTime > LocalDateTime.now() }
|
||||||
|
}
|
||||||
|
else -> { allHunts }
|
||||||
|
}
|
||||||
|
return filteredHunts.map { it.toDomain() }
|
||||||
|
}
|
||||||
|
|
||||||
fun createHunt(hunt: Hunt): Hunt {
|
fun createHunt(hunt: Hunt): Hunt {
|
||||||
return huntRepository.save(hunt.toRecord()).toDomain()
|
return huntRepository.save(hunt.toRecord()).toDomain()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package net.halfbinary.scavengerhuntapi.service
|
||||||
|
|
||||||
|
import net.halfbinary.scavengerhuntapi.error.exception.NotFoundException
|
||||||
|
import net.halfbinary.scavengerhuntapi.model.converter.toDomain
|
||||||
|
import net.halfbinary.scavengerhuntapi.model.domain.Hunter
|
||||||
|
import net.halfbinary.scavengerhuntapi.repository.HunterRepository
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class HunterService(private val hunterRepository: HunterRepository) {
|
||||||
|
fun getHunterByEmail(email: String): Hunter {
|
||||||
|
return hunterRepository.findByEmail(email)?.toDomain()
|
||||||
|
?: throw NotFoundException("No hunter with email $email found")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user