Make amenities global and super-admin managed
All checks were successful
build-and-deploy / build-deploy (push) Successful in 27s
All checks were successful
build-and-deploy / build-deploy (push) Successful in 27s
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
package com.android.trisolarisserver.controller
|
||||
|
||||
import com.android.trisolarisserver.component.PropertyAccess
|
||||
import com.android.trisolarisserver.controller.dto.AmenityResponse
|
||||
import com.android.trisolarisserver.controller.dto.AmenityUpsertRequest
|
||||
import com.android.trisolarisserver.models.property.Role
|
||||
import com.android.trisolarisserver.models.room.RoomAmenity
|
||||
import com.android.trisolarisserver.repo.PropertyRepo
|
||||
import com.android.trisolarisserver.repo.AppUserRepo
|
||||
import com.android.trisolarisserver.repo.RoomAmenityRepo
|
||||
import com.android.trisolarisserver.security.MyPrincipal
|
||||
import org.springframework.http.HttpStatus
|
||||
@@ -23,43 +21,32 @@ import org.springframework.web.server.ResponseStatusException
|
||||
import java.util.UUID
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/properties/{propertyId}/amenities")
|
||||
@RequestMapping("/amenities")
|
||||
class RoomAmenities(
|
||||
private val propertyAccess: PropertyAccess,
|
||||
private val roomAmenityRepo: RoomAmenityRepo,
|
||||
private val propertyRepo: PropertyRepo
|
||||
private val appUserRepo: AppUserRepo
|
||||
) {
|
||||
|
||||
@GetMapping
|
||||
fun listAmenities(
|
||||
@PathVariable propertyId: UUID,
|
||||
@AuthenticationPrincipal principal: MyPrincipal?
|
||||
): List<AmenityResponse> {
|
||||
requirePrincipal(principal)
|
||||
propertyAccess.requireMember(propertyId, principal!!.userId)
|
||||
return roomAmenityRepo.findByPropertyIdOrderByName(propertyId).map { it.toResponse() }
|
||||
return roomAmenityRepo.findAllByOrderByName().map { it.toResponse() }
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
fun createAmenity(
|
||||
@PathVariable propertyId: UUID,
|
||||
@AuthenticationPrincipal principal: MyPrincipal?,
|
||||
@RequestBody request: AmenityUpsertRequest
|
||||
): AmenityResponse {
|
||||
requirePrincipal(principal)
|
||||
propertyAccess.requireMember(propertyId, principal!!.userId)
|
||||
propertyAccess.requireAnyRole(propertyId, principal.userId, Role.ADMIN, Role.MANAGER)
|
||||
requireSuperAdmin(principal)
|
||||
|
||||
if (roomAmenityRepo.existsByPropertyIdAndName(propertyId, request.name)) {
|
||||
throw ResponseStatusException(HttpStatus.CONFLICT, "Amenity already exists for property")
|
||||
}
|
||||
|
||||
val property = propertyRepo.findById(propertyId).orElseThrow {
|
||||
ResponseStatusException(HttpStatus.NOT_FOUND, "Property not found")
|
||||
if (roomAmenityRepo.existsByName(request.name)) {
|
||||
throw ResponseStatusException(HttpStatus.CONFLICT, "Amenity already exists")
|
||||
}
|
||||
val amenity = RoomAmenity(
|
||||
property = property,
|
||||
name = request.name,
|
||||
category = request.category,
|
||||
iconKey = request.iconKey,
|
||||
@@ -70,20 +57,17 @@ class RoomAmenities(
|
||||
|
||||
@PutMapping("/{amenityId}")
|
||||
fun updateAmenity(
|
||||
@PathVariable propertyId: UUID,
|
||||
@PathVariable amenityId: UUID,
|
||||
@AuthenticationPrincipal principal: MyPrincipal?,
|
||||
@RequestBody request: AmenityUpsertRequest
|
||||
): AmenityResponse {
|
||||
requirePrincipal(principal)
|
||||
propertyAccess.requireMember(propertyId, principal!!.userId)
|
||||
propertyAccess.requireAnyRole(propertyId, principal.userId, Role.ADMIN, Role.MANAGER)
|
||||
requireSuperAdmin(principal)
|
||||
|
||||
val amenity = roomAmenityRepo.findByIdAndPropertyId(amenityId, propertyId)
|
||||
val amenity = roomAmenityRepo.findById(amenityId).orElse(null)
|
||||
?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Amenity not found")
|
||||
|
||||
if (roomAmenityRepo.existsByPropertyIdAndNameAndIdNot(propertyId, request.name, amenityId)) {
|
||||
throw ResponseStatusException(HttpStatus.CONFLICT, "Amenity already exists for property")
|
||||
if (roomAmenityRepo.existsByNameAndIdNot(request.name, amenityId)) {
|
||||
throw ResponseStatusException(HttpStatus.CONFLICT, "Amenity already exists")
|
||||
}
|
||||
|
||||
amenity.name = request.name
|
||||
@@ -96,15 +80,12 @@ class RoomAmenities(
|
||||
@DeleteMapping("/{amenityId}")
|
||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||
fun deleteAmenity(
|
||||
@PathVariable propertyId: UUID,
|
||||
@PathVariable amenityId: UUID,
|
||||
@AuthenticationPrincipal principal: MyPrincipal?
|
||||
) {
|
||||
requirePrincipal(principal)
|
||||
propertyAccess.requireMember(propertyId, principal!!.userId)
|
||||
propertyAccess.requireAnyRole(propertyId, principal.userId, Role.ADMIN, Role.MANAGER)
|
||||
requireSuperAdmin(principal)
|
||||
|
||||
val amenity = roomAmenityRepo.findByIdAndPropertyId(amenityId, propertyId)
|
||||
val amenity = roomAmenityRepo.findById(amenityId).orElse(null)
|
||||
?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Amenity not found")
|
||||
|
||||
roomAmenityRepo.delete(amenity)
|
||||
@@ -115,14 +96,24 @@ class RoomAmenities(
|
||||
throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Missing principal")
|
||||
}
|
||||
}
|
||||
|
||||
private fun requireSuperAdmin(principal: MyPrincipal?) {
|
||||
if (principal == null) {
|
||||
throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Missing principal")
|
||||
}
|
||||
val user = appUserRepo.findById(principal.userId).orElseThrow {
|
||||
ResponseStatusException(HttpStatus.UNAUTHORIZED, "User not found")
|
||||
}
|
||||
if (!user.superAdmin) {
|
||||
throw ResponseStatusException(HttpStatus.FORBIDDEN, "Super admin only")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun RoomAmenity.toResponse(): AmenityResponse {
|
||||
val id = id ?: throw ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Amenity id missing")
|
||||
val propertyId = property.id ?: throw ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Property id missing")
|
||||
return AmenityResponse(
|
||||
id = id,
|
||||
propertyId = propertyId,
|
||||
name = name,
|
||||
category = category,
|
||||
iconKey = iconKey,
|
||||
|
||||
Reference in New Issue
Block a user