Make amenities global and super-admin managed
All checks were successful
build-and-deploy / build-deploy (push) Successful in 27s

This commit is contained in:
androidlover5842
2026-01-27 04:33:51 +05:30
parent c3ec6e8d4a
commit eb0b99f55a
5 changed files with 34 additions and 55 deletions

View File

@@ -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,