Add amenities and size fields to room types
All checks were successful
build-and-deploy / build-deploy (push) Successful in 27s

This commit is contained in:
androidlover5842
2026-01-27 04:04:30 +05:30
parent f9c31a4d59
commit a0a9ce4d31
8 changed files with 244 additions and 6 deletions

View File

@@ -0,0 +1,122 @@
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.RoomAmenityRepo
import com.android.trisolarisserver.security.MyPrincipal
import org.springframework.http.HttpStatus
import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.PutMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.server.ResponseStatusException
import java.util.UUID
@RestController
@RequestMapping("/properties/{propertyId}/amenities")
class RoomAmenities(
private val propertyAccess: PropertyAccess,
private val roomAmenityRepo: RoomAmenityRepo,
private val propertyRepo: PropertyRepo
) {
@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() }
}
@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)
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")
}
val amenity = RoomAmenity(
property = property,
name = request.name
)
return roomAmenityRepo.save(amenity).toResponse()
}
@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)
val amenity = roomAmenityRepo.findByIdAndPropertyId(amenityId, propertyId)
?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Amenity not found")
if (roomAmenityRepo.existsByPropertyIdAndNameAndIdNot(propertyId, request.name, amenityId)) {
throw ResponseStatusException(HttpStatus.CONFLICT, "Amenity already exists for property")
}
amenity.name = request.name
return roomAmenityRepo.save(amenity).toResponse()
}
@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)
val amenity = roomAmenityRepo.findByIdAndPropertyId(amenityId, propertyId)
?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Amenity not found")
roomAmenityRepo.delete(amenity)
}
private fun requirePrincipal(principal: MyPrincipal?) {
if (principal == null) {
throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Missing principal")
}
}
}
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
)
}