Compare commits
4 Commits
8ff73cda2b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 3b5046f1db | |||
| 5e2976180c | |||
| 74391f8a46 | |||
| 4049dbbdaa |
@@ -9,11 +9,13 @@ import net.halfbinary.scavengerhuntapi.model.converter.toDomain
|
|||||||
import net.halfbinary.scavengerhuntapi.model.converter.toResponse
|
import net.halfbinary.scavengerhuntapi.model.converter.toResponse
|
||||||
import net.halfbinary.scavengerhuntapi.model.request.HuntCreateRequest
|
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.request.HuntUpdateRequest
|
||||||
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 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.web.bind.annotation.GetMapping
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.PatchMapping
|
||||||
import org.springframework.web.bind.annotation.PathVariable
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
import org.springframework.web.bind.annotation.PostMapping
|
import org.springframework.web.bind.annotation.PostMapping
|
||||||
import org.springframework.web.bind.annotation.RequestBody
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
@@ -44,6 +46,12 @@ class HuntController(private val huntService: HuntService) {
|
|||||||
return ResponseEntity.ok(huntService.getAllHunts(HuntStatus.UNSTARTED).map { it.toResponse() })
|
return ResponseEntity.ok(huntService.getAllHunts(HuntStatus.UNSTARTED).map { it.toResponse() })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/ongoing")
|
||||||
|
@Operation(summary = "Gets list of all ongoing Hunts")
|
||||||
|
fun getOngoingHunts(): ResponseEntity<List<HuntResponse>> {
|
||||||
|
return ResponseEntity.ok(huntService.getAllHunts(HuntStatus.ONGOING).map { it.toResponse() })
|
||||||
|
}
|
||||||
|
|
||||||
@PreAuthorize("hasRole('ADMIN')")
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
@Tag(name = "Admin")
|
@Tag(name = "Admin")
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@@ -52,6 +60,14 @@ class HuntController(private val huntService: HuntService) {
|
|||||||
return ResponseEntity.ok(huntService.createHunt(huntRequest.toDomain()).toResponse())
|
return ResponseEntity.ok(huntService.createHunt(huntRequest.toDomain()).toResponse())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
@Tag(name = "Admin")
|
||||||
|
@PatchMapping("/{id}")
|
||||||
|
@Operation(summary = "Updates details of the specified Hunt")
|
||||||
|
fun updateHunt(@PathVariable("id") huntId: HuntId, @RequestBody body: HuntUpdateRequest): ResponseEntity<HuntResponse> {
|
||||||
|
return ResponseEntity.ok(huntService.updateHunt(huntId, body).toResponse())
|
||||||
|
}
|
||||||
|
|
||||||
@PreAuthorize("hasRole('ADMIN')")
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
@Tag(name = "Admin")
|
@Tag(name = "Admin")
|
||||||
@GetMapping("/hunter/{hunterId}")
|
@GetMapping("/hunter/{hunterId}")
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import net.halfbinary.scavengerhuntapi.model.ItemId
|
|||||||
import net.halfbinary.scavengerhuntapi.model.PhotoId
|
import net.halfbinary.scavengerhuntapi.model.PhotoId
|
||||||
import net.halfbinary.scavengerhuntapi.model.TeamId
|
import net.halfbinary.scavengerhuntapi.model.TeamId
|
||||||
import net.halfbinary.scavengerhuntapi.model.converter.toResponse
|
import net.halfbinary.scavengerhuntapi.model.converter.toResponse
|
||||||
|
import net.halfbinary.scavengerhuntapi.model.converter.toSummaryResponse
|
||||||
import net.halfbinary.scavengerhuntapi.model.request.TeamRequest
|
import net.halfbinary.scavengerhuntapi.model.request.TeamRequest
|
||||||
|
import net.halfbinary.scavengerhuntapi.model.response.HunterSummaryResponse
|
||||||
import net.halfbinary.scavengerhuntapi.model.response.PhotoResponse
|
import net.halfbinary.scavengerhuntapi.model.response.PhotoResponse
|
||||||
import net.halfbinary.scavengerhuntapi.model.response.TeamItemResponse
|
import net.halfbinary.scavengerhuntapi.model.response.TeamItemResponse
|
||||||
import net.halfbinary.scavengerhuntapi.model.response.TeamResponse
|
import net.halfbinary.scavengerhuntapi.model.response.TeamResponse
|
||||||
@@ -47,6 +49,12 @@ class TeamController(private val teamService: TeamService, private val photoServ
|
|||||||
return ResponseEntity.ok(teamService.getTeamFromHunt(huntId, teamId).toResponse())
|
return ResponseEntity.ok(teamService.getTeamFromHunt(huntId, teamId).toResponse())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{teamId}/hunter")
|
||||||
|
@Operation(summary = "Get all Hunters for the specified Team in the specified Hunt")
|
||||||
|
fun getHuntersForTeam(@PathVariable huntId: HuntId, @PathVariable teamId: TeamId): ResponseEntity<List<HunterSummaryResponse>> {
|
||||||
|
return ResponseEntity.ok(teamService.getHuntersForTeam(huntId, teamId).map { it.toSummaryResponse() })
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/{teamId}/item/{itemId}")
|
@GetMapping("/{teamId}/item/{itemId}")
|
||||||
@Operation(summary = "Get found/not found status about the Item for the specified Team, Hunt, and Item")
|
@Operation(summary = "Get found/not found status about the Item for the specified Team, Hunt, and Item")
|
||||||
fun getItemForTeam(@PathVariable huntId: HuntId,
|
fun getItemForTeam(@PathVariable huntId: HuntId,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package net.halfbinary.scavengerhuntapi.model.converter
|
|||||||
import net.halfbinary.scavengerhuntapi.model.domain.Hunter
|
import net.halfbinary.scavengerhuntapi.model.domain.Hunter
|
||||||
import net.halfbinary.scavengerhuntapi.model.record.HunterRecord
|
import net.halfbinary.scavengerhuntapi.model.record.HunterRecord
|
||||||
import net.halfbinary.scavengerhuntapi.model.request.HunterSignupRequest
|
import net.halfbinary.scavengerhuntapi.model.request.HunterSignupRequest
|
||||||
|
import net.halfbinary.scavengerhuntapi.model.response.HunterSummaryResponse
|
||||||
|
|
||||||
fun HunterSignupRequest.toDomain(): Hunter {
|
fun HunterSignupRequest.toDomain(): Hunter {
|
||||||
return Hunter(
|
return Hunter(
|
||||||
@@ -19,4 +20,8 @@ fun Hunter.toRecord(): HunterRecord {
|
|||||||
|
|
||||||
fun HunterRecord.toDomain(): Hunter {
|
fun HunterRecord.toDomain(): Hunter {
|
||||||
return Hunter(id, email, name, password, isAdmin)
|
return Hunter(id, email, name, password, isAdmin)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Hunter.toSummaryResponse(): HunterSummaryResponse {
|
||||||
|
return HunterSummaryResponse(id, name)
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
package net.halfbinary.scavengerhuntapi.model.domain
|
package net.halfbinary.scavengerhuntapi.model.domain
|
||||||
|
|
||||||
import net.halfbinary.scavengerhuntapi.model.HuntId
|
import net.halfbinary.scavengerhuntapi.model.HuntId
|
||||||
import java.time.LocalDateTime
|
import java.time.OffsetDateTime
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
data class Hunt(
|
data class Hunt(
|
||||||
val id: HuntId = UUID.randomUUID(),
|
val id: HuntId = UUID.randomUUID(),
|
||||||
val title: String,
|
val title: String,
|
||||||
val startDateTime: LocalDateTime,
|
val startDateTime: OffsetDateTime,
|
||||||
val endDateTime: LocalDateTime,
|
val endDateTime: OffsetDateTime,
|
||||||
val isTerminated: Boolean
|
val isTerminated: Boolean
|
||||||
) {
|
) {
|
||||||
val isOngoing: Boolean
|
val isOngoing: Boolean
|
||||||
get() = !isTerminated && startDateTime < LocalDateTime.now() && endDateTime > LocalDateTime.now()
|
get() = !isTerminated && startDateTime < OffsetDateTime.now() && endDateTime > OffsetDateTime.now()
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ import net.halfbinary.scavengerhuntapi.model.HunterId
|
|||||||
import net.halfbinary.scavengerhuntapi.model.ItemId
|
import net.halfbinary.scavengerhuntapi.model.ItemId
|
||||||
import net.halfbinary.scavengerhuntapi.model.PhotoId
|
import net.halfbinary.scavengerhuntapi.model.PhotoId
|
||||||
import net.halfbinary.scavengerhuntapi.model.PhotoStatus
|
import net.halfbinary.scavengerhuntapi.model.PhotoStatus
|
||||||
import java.time.LocalDateTime
|
import java.time.OffsetDateTime
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
data class Photo(
|
data class Photo(
|
||||||
@@ -13,7 +13,7 @@ data class Photo(
|
|||||||
val itemId: ItemId,
|
val itemId: ItemId,
|
||||||
val huntId: HuntId,
|
val huntId: HuntId,
|
||||||
val hunterId: HunterId,
|
val hunterId: HunterId,
|
||||||
val foundDateTime: LocalDateTime,
|
val foundDateTime: OffsetDateTime,
|
||||||
val status: PhotoStatus,
|
val status: PhotoStatus,
|
||||||
val statusChangeDateTime: LocalDateTime
|
val statusChangeDateTime: OffsetDateTime
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import jakarta.persistence.Entity
|
|||||||
import jakarta.persistence.Id
|
import jakarta.persistence.Id
|
||||||
import jakarta.persistence.Table
|
import jakarta.persistence.Table
|
||||||
import net.halfbinary.scavengerhuntapi.model.HuntId
|
import net.halfbinary.scavengerhuntapi.model.HuntId
|
||||||
import java.time.LocalDateTime
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a scavenger hunt event
|
* Represents a scavenger hunt event
|
||||||
@@ -16,7 +16,7 @@ data class HuntRecord(
|
|||||||
@Id
|
@Id
|
||||||
val id: HuntId,
|
val id: HuntId,
|
||||||
val title: String,
|
val title: String,
|
||||||
val startDateTime: LocalDateTime,
|
val startDateTime: OffsetDateTime,
|
||||||
val endDateTime: LocalDateTime,
|
val endDateTime: OffsetDateTime,
|
||||||
val isTerminated: Boolean
|
val isTerminated: Boolean
|
||||||
)
|
)
|
||||||
@@ -8,7 +8,7 @@ import net.halfbinary.scavengerhuntapi.model.HunterId
|
|||||||
import net.halfbinary.scavengerhuntapi.model.ItemId
|
import net.halfbinary.scavengerhuntapi.model.ItemId
|
||||||
import net.halfbinary.scavengerhuntapi.model.PhotoId
|
import net.halfbinary.scavengerhuntapi.model.PhotoId
|
||||||
import net.halfbinary.scavengerhuntapi.model.PhotoStatus
|
import net.halfbinary.scavengerhuntapi.model.PhotoStatus
|
||||||
import java.time.LocalDateTime
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a found Item for a Hunt by a Hunter
|
* Represents a found Item for a Hunt by a Hunter
|
||||||
@@ -21,7 +21,7 @@ data class PhotoRecord(
|
|||||||
val itemId: ItemId,
|
val itemId: ItemId,
|
||||||
val huntId: HuntId,
|
val huntId: HuntId,
|
||||||
val hunterId: HunterId,
|
val hunterId: HunterId,
|
||||||
val foundDateTime: LocalDateTime,
|
val foundDateTime: OffsetDateTime,
|
||||||
val status: PhotoStatus,
|
val status: PhotoStatus,
|
||||||
val statusChangeDateTime: LocalDateTime,
|
val statusChangeDateTime: OffsetDateTime,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import jakarta.persistence.Entity
|
|||||||
import jakarta.persistence.Id
|
import jakarta.persistence.Id
|
||||||
import jakarta.persistence.Table
|
import jakarta.persistence.Table
|
||||||
import net.halfbinary.scavengerhuntapi.model.RefreshId
|
import net.halfbinary.scavengerhuntapi.model.RefreshId
|
||||||
import java.time.LocalDateTime
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "refresh_token")
|
@Table(name = "refresh_token")
|
||||||
@@ -12,5 +12,5 @@ data class RefreshTokenRecord(
|
|||||||
@Id
|
@Id
|
||||||
val token: RefreshId,
|
val token: RefreshId,
|
||||||
val email: String,
|
val email: String,
|
||||||
val expiryDateTime: LocalDateTime
|
val expiryDateTime: OffsetDateTime
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ package net.halfbinary.scavengerhuntapi.model.request
|
|||||||
|
|
||||||
import jakarta.validation.constraints.Future
|
import jakarta.validation.constraints.Future
|
||||||
import jakarta.validation.constraints.NotBlank
|
import jakarta.validation.constraints.NotBlank
|
||||||
import java.time.LocalDateTime
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
data class HuntCreateRequest(
|
data class HuntCreateRequest(
|
||||||
@field:NotBlank(message = "Hunt title is required")
|
@field:NotBlank(message = "Hunt title is required")
|
||||||
val title: String,
|
val title: String,
|
||||||
@field:Future
|
@field:Future
|
||||||
val startDateTime: LocalDateTime,
|
val startDateTime: OffsetDateTime,
|
||||||
@field:Future
|
@field:Future
|
||||||
val endDateTime: LocalDateTime,
|
val endDateTime: OffsetDateTime,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package net.halfbinary.scavengerhuntapi.model.request
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
|
data class HuntUpdateRequest(
|
||||||
|
val title: String?,
|
||||||
|
val startDateTime: OffsetDateTime?,
|
||||||
|
val endDateTime: OffsetDateTime?,
|
||||||
|
val isTerminated: Boolean?
|
||||||
|
)
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package net.halfbinary.scavengerhuntapi.model.request
|
package net.halfbinary.scavengerhuntapi.model.request
|
||||||
|
|
||||||
import jakarta.validation.constraints.NotBlank
|
import jakarta.validation.constraints.NotNull
|
||||||
import net.halfbinary.scavengerhuntapi.model.PhotoStatus
|
import net.halfbinary.scavengerhuntapi.model.PhotoStatus
|
||||||
|
|
||||||
data class ReviewPhotoRequest(
|
data class ReviewPhotoRequest(
|
||||||
@field:NotBlank(message = "Status must not be blank")
|
@field:NotNull(message = "Status must not be null")
|
||||||
val status: PhotoStatus
|
val status: PhotoStatus
|
||||||
)
|
)
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package net.halfbinary.scavengerhuntapi.model.response
|
package net.halfbinary.scavengerhuntapi.model.response
|
||||||
|
|
||||||
import net.halfbinary.scavengerhuntapi.model.HuntId
|
import net.halfbinary.scavengerhuntapi.model.HuntId
|
||||||
import java.time.LocalDateTime
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
data class HuntResponse(
|
data class HuntResponse(
|
||||||
val id: HuntId,
|
val id: HuntId,
|
||||||
val title: String,
|
val title: String,
|
||||||
val startDateTime: LocalDateTime,
|
val startDateTime: OffsetDateTime,
|
||||||
val endDateTime: LocalDateTime,
|
val endDateTime: OffsetDateTime,
|
||||||
val isTerminated: Boolean
|
val isTerminated: Boolean
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package net.halfbinary.scavengerhuntapi.model.response
|
||||||
|
|
||||||
|
import net.halfbinary.scavengerhuntapi.model.HunterId
|
||||||
|
|
||||||
|
data class HunterSummaryResponse(
|
||||||
|
val id: HunterId,
|
||||||
|
val name: String
|
||||||
|
)
|
||||||
@@ -2,12 +2,12 @@ package net.halfbinary.scavengerhuntapi.model.response
|
|||||||
|
|
||||||
import net.halfbinary.scavengerhuntapi.model.PhotoId
|
import net.halfbinary.scavengerhuntapi.model.PhotoId
|
||||||
import net.halfbinary.scavengerhuntapi.model.PhotoStatus
|
import net.halfbinary.scavengerhuntapi.model.PhotoStatus
|
||||||
import java.time.LocalDateTime
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
data class PhotoResponse(
|
data class PhotoResponse(
|
||||||
val id: PhotoId,
|
val id: PhotoId,
|
||||||
val hunterName: String,
|
val hunterName: String,
|
||||||
val photoUploadDateTime: LocalDateTime,
|
val photoUploadDateTime: OffsetDateTime,
|
||||||
val photoStatus: PhotoStatus,
|
val photoStatus: PhotoStatus,
|
||||||
val photoStatusChangeDateTime: LocalDateTime,
|
val photoStatusChangeDateTime: OffsetDateTime,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -11,13 +11,14 @@ import net.halfbinary.scavengerhuntapi.model.domain.Hunt
|
|||||||
import net.halfbinary.scavengerhuntapi.model.domain.HuntItem
|
import net.halfbinary.scavengerhuntapi.model.domain.HuntItem
|
||||||
import net.halfbinary.scavengerhuntapi.model.domain.Item
|
import net.halfbinary.scavengerhuntapi.model.domain.Item
|
||||||
import net.halfbinary.scavengerhuntapi.model.request.HuntStatus
|
import net.halfbinary.scavengerhuntapi.model.request.HuntStatus
|
||||||
|
import net.halfbinary.scavengerhuntapi.model.request.HuntUpdateRequest
|
||||||
import net.halfbinary.scavengerhuntapi.model.request.ItemUpdateRequest
|
import net.halfbinary.scavengerhuntapi.model.request.ItemUpdateRequest
|
||||||
import net.halfbinary.scavengerhuntapi.repository.HuntItemRepository
|
import net.halfbinary.scavengerhuntapi.repository.HuntItemRepository
|
||||||
import net.halfbinary.scavengerhuntapi.repository.HuntRepository
|
import net.halfbinary.scavengerhuntapi.repository.HuntRepository
|
||||||
import net.halfbinary.scavengerhuntapi.repository.ItemRepository
|
import net.halfbinary.scavengerhuntapi.repository.ItemRepository
|
||||||
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
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class HuntService(
|
class HuntService(
|
||||||
@@ -48,16 +49,16 @@ class HuntService(
|
|||||||
val filteredHunts = when (status) {
|
val filteredHunts = when (status) {
|
||||||
HuntStatus.ONGOING -> {
|
HuntStatus.ONGOING -> {
|
||||||
allHunts
|
allHunts
|
||||||
.filter { !it.isTerminated && it.startDateTime < LocalDateTime.now() && it.endDateTime > LocalDateTime.now() }
|
.filter { !it.isTerminated && it.startDateTime < OffsetDateTime.now() && it.endDateTime > OffsetDateTime.now() }
|
||||||
.toList()
|
.toList()
|
||||||
}
|
}
|
||||||
HuntStatus.CLOSED -> {
|
HuntStatus.CLOSED -> {
|
||||||
allHunts
|
allHunts
|
||||||
.filter { it.isTerminated || it.endDateTime < LocalDateTime.now() }
|
.filter { it.isTerminated || it.endDateTime < OffsetDateTime.now() }
|
||||||
}
|
}
|
||||||
HuntStatus.UNSTARTED -> {
|
HuntStatus.UNSTARTED -> {
|
||||||
allHunts
|
allHunts
|
||||||
.filter { !it.isTerminated && it.startDateTime > LocalDateTime.now() }
|
.filter { !it.isTerminated && it.startDateTime > OffsetDateTime.now() }
|
||||||
}
|
}
|
||||||
else -> { allHunts }
|
else -> { allHunts }
|
||||||
}
|
}
|
||||||
@@ -68,6 +69,18 @@ class HuntService(
|
|||||||
return huntRepository.save(hunt.toRecord()).toDomain()
|
return huntRepository.save(hunt.toRecord()).toDomain()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateHunt(huntId: HuntId, request: HuntUpdateRequest): Hunt {
|
||||||
|
val existing = huntRepository.findByIdOrNull(huntId)
|
||||||
|
?: throw NotFoundException("No hunt with id $huntId found")
|
||||||
|
val updated = existing.copy(
|
||||||
|
title = request.title ?: existing.title,
|
||||||
|
startDateTime = request.startDateTime ?: existing.startDateTime,
|
||||||
|
endDateTime = request.endDateTime ?: existing.endDateTime,
|
||||||
|
isTerminated = request.isTerminated ?: existing.isTerminated
|
||||||
|
)
|
||||||
|
return huntRepository.save(updated).toDomain()
|
||||||
|
}
|
||||||
|
|
||||||
fun getItemsForHunt(huntId: HuntId, email: String): List<Item> {
|
fun getItemsForHunt(huntId: HuntId, email: String): List<Item> {
|
||||||
val hunt = huntRepository.findByIdOrNull(huntId)?.toDomain() ?: throw NotFoundException("No hunt with id $huntId found")
|
val hunt = huntRepository.findByIdOrNull(huntId)?.toDomain() ?: throw NotFoundException("No hunt with id $huntId found")
|
||||||
val hunter = hunterService.getHunterByEmail(email)
|
val hunter = hunterService.getHunterByEmail(email)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import org.springframework.stereotype.Service
|
|||||||
import org.springframework.web.multipart.MultipartFile
|
import org.springframework.web.multipart.MultipartFile
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.time.LocalDateTime
|
import java.time.OffsetDateTime
|
||||||
|
|
||||||
private const val PHOTO_NOT_FOUND = "Photo not found"
|
private const val PHOTO_NOT_FOUND = "Photo not found"
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ class PhotoService(
|
|||||||
throw BadFileException("Image type is not supported")
|
throw BadFileException("Image type is not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
val now = LocalDateTime.now()
|
val now = OffsetDateTime.now()
|
||||||
val photo = Photo(
|
val photo = Photo(
|
||||||
itemId = itemId,
|
itemId = itemId,
|
||||||
huntId = huntId,
|
huntId = huntId,
|
||||||
@@ -171,7 +171,7 @@ class PhotoService(
|
|||||||
|
|
||||||
if (photoRecord.status == PhotoStatus.APPROVED) throw ConflictException("Cannot remove an approved photo")
|
if (photoRecord.status == PhotoStatus.APPROVED) throw ConflictException("Cannot remove an approved photo")
|
||||||
|
|
||||||
photoRepository.save(photoRecord.copy(status = PhotoStatus.REMOVED, statusChangeDateTime = LocalDateTime.now()))
|
photoRepository.save(photoRecord.copy(status = PhotoStatus.REMOVED, statusChangeDateTime = OffsetDateTime.now()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getItemPhotos(huntId: HuntId, teamId: TeamId, itemId: ItemId, email: String): List<PhotoResponse> {
|
fun getItemPhotos(huntId: HuntId, teamId: TeamId, itemId: ItemId, email: String): List<PhotoResponse> {
|
||||||
@@ -197,7 +197,7 @@ class PhotoService(
|
|||||||
fun updatePhotoStatus(photoId: PhotoId, status: PhotoStatus) {
|
fun updatePhotoStatus(photoId: PhotoId, status: PhotoStatus) {
|
||||||
val record = photoRepository.findByIdOrNull(photoId)
|
val record = photoRepository.findByIdOrNull(photoId)
|
||||||
?: throw NotFoundException(PHOTO_NOT_FOUND)
|
?: throw NotFoundException(PHOTO_NOT_FOUND)
|
||||||
photoRepository.save(record.copy(status = status, statusChangeDateTime = LocalDateTime.now()))
|
photoRepository.save(record.copy(status = status, statusChangeDateTime = OffsetDateTime.now()))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toJpeg(bytes: ByteArray): ByteArray {
|
private fun toJpeg(bytes: ByteArray): ByteArray {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import net.halfbinary.scavengerhuntapi.repository.RefreshTokenRepository
|
|||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
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
|
import java.time.OffsetDateTime
|
||||||
import java.time.temporal.ChronoUnit
|
import java.time.temporal.ChronoUnit
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -33,11 +33,11 @@ class RefreshTokenService(private val refreshTokenRepository: RefreshTokenReposi
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun generateRefreshToken(email: String): RefreshId {
|
fun generateRefreshToken(email: String): RefreshId {
|
||||||
return refreshTokenRepository.save(RefreshTokenRecord(RefreshId.randomUUID(), email, LocalDateTime.now().plus(1, ChronoUnit.MONTHS))).token
|
return refreshTokenRepository.save(RefreshTokenRecord(RefreshId.randomUUID(), email, OffsetDateTime.now().plus(1, ChronoUnit.MONTHS))).token
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isTokenExpired(token: RefreshTokenRecord): Boolean {
|
fun isTokenExpired(token: RefreshTokenRecord): Boolean {
|
||||||
return token.expiryDateTime.isBefore(LocalDateTime.now())
|
return token.expiryDateTime.isBefore(OffsetDateTime.now())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getToken(token: RefreshId): RefreshTokenRecord? {
|
fun getToken(token: RefreshId): RefreshTokenRecord? {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import net.halfbinary.scavengerhuntapi.model.HunterId
|
|||||||
import net.halfbinary.scavengerhuntapi.model.TeamId
|
import net.halfbinary.scavengerhuntapi.model.TeamId
|
||||||
import net.halfbinary.scavengerhuntapi.model.converter.toDomain
|
import net.halfbinary.scavengerhuntapi.model.converter.toDomain
|
||||||
import net.halfbinary.scavengerhuntapi.model.converter.toRecord
|
import net.halfbinary.scavengerhuntapi.model.converter.toRecord
|
||||||
|
import net.halfbinary.scavengerhuntapi.model.domain.Hunter
|
||||||
import net.halfbinary.scavengerhuntapi.model.domain.Team
|
import net.halfbinary.scavengerhuntapi.model.domain.Team
|
||||||
import net.halfbinary.scavengerhuntapi.model.domain.TeamHunt
|
import net.halfbinary.scavengerhuntapi.model.domain.TeamHunt
|
||||||
import net.halfbinary.scavengerhuntapi.model.record.HunterTeamRecord
|
import net.halfbinary.scavengerhuntapi.model.record.HunterTeamRecord
|
||||||
@@ -54,6 +55,12 @@ class TeamService(
|
|||||||
return hunterTeamRepository.findByTeamId(teamId).map { it.hunterId }.toSet()
|
return hunterTeamRepository.findByTeamId(teamId).map { it.hunterId }.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getHuntersForTeam(huntId: HuntId, teamId: TeamId): List<Hunter> {
|
||||||
|
getTeamFromHunt(huntId, teamId)
|
||||||
|
val hunterIds = getHunterIdsForTeam(teamId)
|
||||||
|
return hunterRepository.findAllById(hunterIds).map { it.toDomain() }
|
||||||
|
}
|
||||||
|
|
||||||
fun joinTeam(teamId: TeamId, email: String) {
|
fun joinTeam(teamId: TeamId, email: String) {
|
||||||
val hunter = hunterRepository.findByEmail(email) ?: throw NotFoundException("No hunter with email $email found")
|
val hunter = hunterRepository.findByEmail(email) ?: throw NotFoundException("No hunter with email $email found")
|
||||||
hunterTeamRepository.save(HunterTeamRecord(UUID.randomUUID(), hunter.id, teamId))
|
hunterTeamRepository.save(HunterTeamRecord(UUID.randomUUID(), hunter.id, teamId))
|
||||||
|
|||||||
Reference in New Issue
Block a user