Files
TrisolarisServer/docs/API_CATALOG.md
androidlover5842 35680287d4
All checks were successful
build-and-deploy / build-deploy (push) Successful in 17s
Generate behavior-first API catalog from controllers
2026-02-04 12:21:48 +05:30

76 KiB

API Catalog

Behavior-first catalog generated from controller source.

  • Total endpoints: 125
  • Notes: validations/errors are extracted from explicit ResponseStatusException checks and shared helper guards.
  • Regenerate: python scripts/generate_api_docs.py

src/main/kotlin/com/android/trisolarisserver/controller/assets/IconFiles.kt

GET /icons/png

  • Handler: listPng (src/main/kotlin/com/android/trisolarisserver/controller/assets/IconFiles.kt:23)
  • Behavior: List resources (list png).
  • Body: none
  • Auth: Public/unspecified
  • Response: 200 List<String>
  • Common errors: none observed in controller checks

GET /icons/png/{filename}

  • Handler: getPng (src/main/kotlin/com/android/trisolarisserver/controller/assets/IconFiles.kt:39)
  • Behavior: Get resource (get png).
  • Path params: filename:String
  • Body: none
  • Auth: Public/unspecified
  • Response: 200 ResponseEntity<FileSystemResource>
  • Common errors: none observed in controller checks

src/main/kotlin/com/android/trisolarisserver/controller/auth/Auth.kt

GET /auth/me

  • Handler: me (src/main/kotlin/com/android/trisolarisserver/controller/auth/Auth.kt:44)
  • Behavior: Me.
  • Body: none
  • Auth: Authenticated user (Firebase)
  • Response: 200 ResponseEntity<AuthResponse>
  • Common errors: none observed in controller checks

PUT /auth/me

  • Handler: updateMe (src/main/kotlin/com/android/trisolarisserver/controller/auth/Auth.kt:54)
  • Behavior: Update resource (update me).
  • Body: UpdateMeRequest { name:String? (optional) }
  • Auth: Authenticated user (Firebase)
  • Response: 200 ResponseEntity<AuthResponse>
  • Common errors: 401 (User not found)

POST /auth/verify

  • Handler: verify (src/main/kotlin/com/android/trisolarisserver/controller/auth/Auth.kt:33)
  • Behavior: Verify.
  • Body: none
  • Auth: Authenticated user (Firebase)
  • Response: 200 ResponseEntity<AuthResponse>
  • Common errors: none observed in controller checks

src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingBalances.kt

GET /properties/{propertyId}/bookings/{bookingId}/balance

  • Handler: getBalance (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingBalances.kt:32)
  • Behavior: Get resource (get balance).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: none
  • Auth: Any property member
  • Response: 200 BookingBalanceResponse
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Booking not found; Booking not found for property)

src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt

GET /properties/{propertyId}/bookings

  • Handler: listBookings (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt:187)
  • Behavior: List resources (list bookings).
  • Path params: propertyId:UUID
  • Query params: status:String? (optional)
  • Body: none
  • Auth: Roles: ADMIN, FINANCE, HOUSEKEEPING, MANAGER, STAFF
  • Response: 200 List<BookingListItem>
  • Validation/guard checks:
    • 400: Invalid status: $value
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Property not found), 400 (Invalid status: $value)

POST /properties/{propertyId}/bookings

  • Handler: createBooking (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt:99)
  • Behavior: Create resource (create booking).
  • Path params: propertyId:UUID
  • Body: BookingCreateRequest { source:String? (optional), expectedCheckInAt:String, expectedCheckOutAt:String, billingMode:String? (optional), billingCheckoutTime:String? (optional), guestPhoneE164:String? (optional), fromCity:String? (optional), toCity:String? (optional), memberRelation:String? (optional), transportMode:String? (optional), childCount:Int? (optional), maleCount:Int? (optional), femaleCount:Int? (optional), expectedGuestCount:Int? (optional), notes:String? (optional) }
  • Side effects: Emits booking SSE updates.
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 201 BookingCreateResponse
  • Validation/guard checks:
    • 400: expectedCheckInAt required
    • 400: expectedCheckOutAt required
    • 400: Invalid date range
    • 400: Transport mode disabled
  • Common errors: 401 (User not found; Missing principal), 403 (Required property role not granted), 404 (Property not found), 400 (expectedCheckInAt required; expectedCheckOutAt required)

GET /properties/{propertyId}/bookings/{bookingId}

  • Handler: getBooking (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt:282)
  • Behavior: Get resource (get booking).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: none
  • Auth: Roles: ADMIN, FINANCE, HOUSEKEEPING, MANAGER, STAFF
  • Response: 200 BookingDetailResponse
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property)

POST /properties/{propertyId}/bookings/{bookingId}/billing-policy

  • Handler: updateBillingPolicy (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt:476)
  • Behavior: Update resource (update billing policy).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: BookingBillingPolicyUpdateRequest { billingMode:String, billingCheckoutTime:String? (optional) }
  • Side effects: Emits booking SSE updates.
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 204 Unit
  • Validation/guard checks:
    • 400: $fieldName required
    • 400: $fieldName must be HH:mm
    • 400: Unknown billing mode
    • 409: Booking closed
  • Common errors: 401 (User not found; Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 400 ($fieldName required; $fieldName must be HH:mm), 409 (Booking closed)

POST /properties/{propertyId}/bookings/{bookingId}/cancel

  • Handler: cancel (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt:695)
  • Behavior: Cancel flow (cancel).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: BookingCancelRequest { cancelledAt:String? (optional), reason:String? (optional) }
  • Side effects: Emits booking SSE updates.
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 204 Unit
  • Validation/guard checks:
    • 409: Cannot cancel checked-in booking
  • Common errors: 401 (User not found; Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 409 (Cannot cancel checked-in booking)

POST /properties/{propertyId}/bookings/{bookingId}/check-in/bulk

  • Handler: bulkCheckIn (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt:353)
  • Behavior: Bulk check in.
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: BookingBulkCheckInRequest { stays:List, transportMode:String? (optional), notes:String? (optional) }
  • Side effects: Emits booking SSE updates. Emits room board SSE updates.
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 201 Unit
  • Validation/guard checks:
    • 400: stays required
    • 400: Duplicate roomId in stays
    • 400: Transport mode disabled
    • 400: Unknown transport mode
    • 409: Booking not open
    • 409: Room not available
    • 409: Room already occupied
  • Common errors: 401 (User not found; Missing principal), 403 (Required property role not granted), 404 (Room not found; Booking not found), 400 (stays required; Duplicate roomId in stays), 409 (Booking not open; Room not available)

POST /properties/{propertyId}/bookings/{bookingId}/check-out

  • Handler: checkOut (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt:527)
  • Behavior: Check out flow (check out).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: BookingCheckOutRequest { checkOutAt:String? (optional), notes:String? (optional) }
  • Side effects: Emits booking SSE updates. Emits room board SSE updates. Writes room-stay audit log.
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 204 Unit
  • Validation/guard checks:
    • 400: Invalid timestamp
    • 409: Booking not checked in
    • 409: Room stay amount is outside allowed range
    • 409: Ledger mismatch: collected amount must be within 20% of expected amount before checkout
  • Common errors: 401 (User not found; Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 400 (Invalid timestamp), 409 (Booking not checked in; Room stay amount is outside allowed range)

POST /properties/{propertyId}/bookings/{bookingId}/expected-dates

  • Handler: updateExpectedDates (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt:430)
  • Behavior: Update resource (update expected dates).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: BookingExpectedDatesUpdateRequest { expectedCheckInAt:String? (optional), expectedCheckOutAt:String? (optional) }
  • Side effects: Emits booking SSE updates.
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 204 Unit
  • Validation/guard checks:
    • 400: Invalid date range
    • 400: Invalid timestamp
    • 409: Cannot change expected check-in after check-in
    • 409: Booking closed
  • Common errors: 401 (User not found; Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 400 (Invalid date range; Invalid timestamp), 409 (Cannot change expected check-in after check-in; Booking closed)

POST /properties/{propertyId}/bookings/{bookingId}/link-guest

  • Handler: linkGuest (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt:326)
  • Behavior: Link guest.
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: BookingLinkGuestRequest { guestId:UUID }
  • Side effects: Emits booking SSE updates.
  • Auth: Any property member
  • Response: 204 Unit
  • Validation/guard checks:
    • 400: Guest not in property
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Guest not found; Booking not found), 400 (Guest not in property)

POST /properties/{propertyId}/bookings/{bookingId}/no-show

  • Handler: noShow (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt:720)
  • Behavior: No-show flow (no show).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: BookingNoShowRequest { noShowAt:String? (optional), reason:String? (optional) }
  • Side effects: Emits booking SSE updates.
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 204 Unit
  • Validation/guard checks:
    • 409: Booking not open
  • Common errors: 401 (User not found; Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 409 (Booking not open)

POST /properties/{propertyId}/bookings/{bookingId}/room-stays/{roomStayId}/check-out

  • Handler: checkOutRoomStay (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt:583)
  • Behavior: Check out flow (check out room stay).
  • Path params: propertyId:UUID, bookingId:UUID, roomStayId:UUID
  • Body: BookingCheckOutRequest { checkOutAt:String? (optional), notes:String? (optional) }
  • Side effects: Emits booking SSE updates. Emits room board SSE updates. Writes room-stay audit log.
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 204 Unit
  • Validation/guard checks:
    • 400: Invalid timestamp
    • 409: Booking not checked in
    • 409: Room stay amount is outside allowed range
    • 409: Minimum stay duration is 1 hour
    • 409: Ledger mismatch: collected amount must be within 20% of expected amount before checkout
  • Common errors: 401 (User not found; Missing principal), 403 (Required property role not granted), 404 (Room stay not found for booking; Booking not found), 400 (Invalid timestamp), 409 (Booking not checked in; Room stay amount is outside allowed range)

GET /properties/{propertyId}/bookings/{bookingId}/stream

  • Handler: streamBooking (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingFlow.kt:302)
  • Behavior: Stream events/data (stream booking).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: none
  • Side effects: Streams SSE events.
  • Auth: Roles: ADMIN, FINANCE, HOUSEKEEPING, MANAGER, STAFF
  • Response: 200 org.springframework.web.servlet.mvc.method.annotation.SseEmitter
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property)

src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingRoomRequests.kt

GET /properties/{propertyId}/bookings/{bookingId}/room-requests

  • Handler: list (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingRoomRequests.kt:103)
  • Behavior: List resources (list).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: none
  • Auth: Roles: ADMIN, FINANCE, HOUSEKEEPING, MANAGER, STAFF
  • Response: 200 List<BookingRoomRequestResponse>
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property)

POST /properties/{propertyId}/bookings/{bookingId}/room-requests

  • Handler: create (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingRoomRequests.kt:48)
  • Behavior: Create resource (create).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: BookingRoomRequestCreateRequest { roomTypeCode:String, quantity:Int, fromAt:String, toAt:String }
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 201 BookingRoomRequestResponse
  • Validation/guard checks:
    • 400: quantity must be > 0
    • 400: fromAt required
    • 400: toAt required
    • 400: Invalid date range
    • 409: Booking closed
    • 409: Insufficient room type availability
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 400 (quantity must be > 0; fromAt required), 409 (Booking closed; Insufficient room type availability)

DELETE /properties/{propertyId}/bookings/{bookingId}/room-requests/{requestId}

  • Handler: cancel (src/main/kotlin/com/android/trisolarisserver/controller/booking/BookingRoomRequests.kt:121)
  • Behavior: Cancel flow (cancel).
  • Path params: propertyId:UUID, bookingId:UUID, requestId:UUID
  • Body: none
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 204 Unit
  • Validation/guard checks:
    • 409: Cannot cancel fulfilled room request
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 409 (Cannot cancel fulfilled room request)

src/main/kotlin/com/android/trisolarisserver/controller/card/IssuedCards.kt

GET /properties/{propertyId}/room-stays/cards/{cardIndex}

  • Handler: getCardByIndex (src/main/kotlin/com/android/trisolarisserver/controller/card/IssuedCards.kt:158)
  • Behavior: Get resource (get card by index).
  • Path params: propertyId:UUID, cardIndex:Int
  • Body: none
  • Auth: Roles: ADMIN, MANAGER
  • Response: 200 IssuedCardResponse
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Card not found)

POST /properties/{propertyId}/room-stays/cards/{cardIndex}/revoke

  • Handler: revoke (src/main/kotlin/com/android/trisolarisserver/controller/card/IssuedCards.kt:138)
  • Behavior: Revoke.
  • Path params: propertyId:UUID, cardIndex:Int
  • Body: none
  • Auth: Roles: ADMIN, MANAGER
  • Response: 200 CardRevokeResponse
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Card not found)

GET /properties/{propertyId}/room-stays/{roomStayId}/cards

  • Handler: list (src/main/kotlin/com/android/trisolarisserver/controller/card/IssuedCards.kt:125)
  • Behavior: List resources (list).
  • Path params: propertyId:UUID, roomStayId:UUID
  • Body: none
  • Auth: Roles: ADMIN, MANAGER, STAFF, SUPERVISOR
  • Response: 200 List<IssuedCardResponse>
  • Common errors: 401 (Missing principal), 404 (Room stay not found for property)

POST /properties/{propertyId}/room-stays/{roomStayId}/cards

  • Handler: issue (src/main/kotlin/com/android/trisolarisserver/controller/card/IssuedCards.kt:83)
  • Behavior: Issue.
  • Path params: propertyId:UUID, roomStayId:UUID
  • Body: IssueCardRequest { cardId:String, cardIndex:Int, issuedAt:String? (optional), expiresAt:String }
  • Auth: Roles: ADMIN, MANAGER
  • Response: 201 IssuedCardResponse
  • Validation/guard checks:
    • 400: cardId required
    • 400: cardIndex required
    • 400: expiresAt required
    • 400: expiresAt must be after issuedAt
    • 409: Active card already exists for room stay
    • 409: Active card already exists for room
    • 409: Room stay is already closed
  • Common errors: 401 (Missing principal; User not found), 403 (Property membership required), 404 (Room stay not found for property), 400 (cardId required; cardIndex required), 409 (Active card already exists for room stay; Active card already exists for room)

POST /properties/{propertyId}/room-stays/{roomStayId}/cards/prepare

  • Handler: prepare (src/main/kotlin/com/android/trisolarisserver/controller/card/IssuedCards.kt:50)
  • Behavior: Prepare.
  • Path params: propertyId:UUID, roomStayId:UUID
  • Body: CardPrepareRequest { expiresAt:String? (optional) }
  • Auth: Roles: ADMIN, MANAGER
  • Response: 201 CardPrepareResponse
  • Validation/guard checks:
    • 400: expiresAt required
    • 400: expiresAt must be after issuedAt
    • 400: Invalid timestamp
    • 409: Room stay is already closed
  • Common errors: 401 (Missing principal; User not found), 403 (Property membership required), 404 (Room stay not found for property; Property not found), 400 (expiresAt required; expiresAt must be after issuedAt), 409 (Room stay is already closed)

src/main/kotlin/com/android/trisolarisserver/controller/card/TemporaryRoomCards.kt

POST /properties/{propertyId}/rooms/{roomId}/cards/prepare-temp

  • Handler: prepareTemporary (src/main/kotlin/com/android/trisolarisserver/controller/card/TemporaryRoomCards.kt:46)
  • Behavior: Prepare temporary.
  • Path params: propertyId:UUID, roomId:UUID
  • Body: none
  • Auth: Roles: ADMIN, MANAGER
  • Response: 201 CardPrepareResponse
  • Common errors: 401 (Missing principal; User not found), 403 (Property membership required), 404 (Room not found; Property not found)

POST /properties/{propertyId}/rooms/{roomId}/cards/temp

  • Handler: issueTemporary (src/main/kotlin/com/android/trisolarisserver/controller/card/TemporaryRoomCards.kt:74)
  • Behavior: Issue temporary.
  • Path params: propertyId:UUID, roomId:UUID
  • Body: IssueTempCardRequest { cardId:String, cardIndex:Int, issuedAt:String? (optional) }
  • Auth: Roles: ADMIN, MANAGER
  • Response: 201 IssuedCardResponse
  • Validation/guard checks:
    • 400: cardId required
    • 400: cardIndex required
    • 400: Invalid timestamp
    • 409: Active card already exists for room
  • Common errors: 401 (Missing principal; User not found), 403 (Property membership required), 404 (Room not found), 400 (cardId required; cardIndex required), 409 (Active card already exists for room)

src/main/kotlin/com/android/trisolarisserver/controller/email/InboundEmailManual.kt

POST /properties/{propertyId}/inbound-emails/manual

  • Handler: uploadManualPdf (src/main/kotlin/com/android/trisolarisserver/controller/email/InboundEmailManual.kt:41)
  • Behavior: Upload manual pdf.
  • Path params: propertyId:UUID
  • Query params: file:MultipartFile (required)
  • Body: none
  • Auth: Roles: ADMIN, MANAGER
  • Response: 201 ManualInboundResponse
  • Validation/guard checks:
    • 400: File is empty
    • 400: Only PDF is supported
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Property not found), 400 (File is empty; Only PDF is supported)

src/main/kotlin/com/android/trisolarisserver/controller/email/InboundEmails.kt

GET /properties/{propertyId}/inbound-emails/{emailId}/file

  • Handler: downloadEmailPdf (src/main/kotlin/com/android/trisolarisserver/controller/email/InboundEmails.kt:32)
  • Behavior: Download email pdf.
  • Path params: propertyId:UUID, emailId:UUID
  • Body: none
  • Auth: Roles: ADMIN, MANAGER
  • Response: 200 ResponseEntity<FileSystemResource>
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Email not found; Email PDF missing)

src/main/kotlin/com/android/trisolarisserver/controller/guest/GuestDocuments.kt

GET /properties/{propertyId}/guests/{guestId}/documents

  • Handler: listDocuments (src/main/kotlin/com/android/trisolarisserver/controller/guest/GuestDocuments.kt:125)
  • Behavior: List resources (list documents).
  • Path params: propertyId:UUID, guestId:UUID
  • Body: none
  • Auth: Roles: ADMIN, MANAGER
  • Response: 200 List<GuestDocumentResponse>
  • Common errors: 401 (Missing principal), 403 (Required property role not granted)

POST /properties/{propertyId}/guests/{guestId}/documents

  • Handler: uploadDocument (src/main/kotlin/com/android/trisolarisserver/controller/guest/GuestDocuments.kt:65)
  • Behavior: Upload document.
  • Path params: propertyId:UUID, guestId:UUID
  • Query params: bookingId:UUID (required)
  • Body: none
  • Side effects: Stores/updates guest document metadata.
  • Auth: Roles: ADMIN, MANAGER
  • Response: 201 GuestDocumentResponse
  • Validation/guard checks:
    • 400: File is empty
    • 400: Video files are not allowed
    • 400: Booking not in property
    • 400: Booking not linked to guest
    • 409: Duplicate document
  • Common errors: 401 (Missing principal; User not found), 403 (Property membership required), 404 (Booking not found; Property or guest not found), 400 (File is empty; Video files are not allowed), 409 (Duplicate document)

GET /properties/{propertyId}/guests/{guestId}/documents/stream

  • Handler: streamDocuments (src/main/kotlin/com/android/trisolarisserver/controller/guest/GuestDocuments.kt:138)
  • Behavior: Stream events/data (stream documents).
  • Path params: propertyId:UUID, guestId:UUID
  • Body: none
  • Side effects: Streams SSE events.
  • Auth: Roles: ADMIN, MANAGER
  • Response: 200 org.springframework.web.servlet.mvc.method.annotation.SseEmitter
  • Common errors: 401 (Missing principal), 403 (Required property role not granted)

DELETE /properties/{propertyId}/guests/{guestId}/documents/{documentId}

  • Handler: deleteDocument (src/main/kotlin/com/android/trisolarisserver/controller/guest/GuestDocuments.kt:184)
  • Behavior: Delete resource (delete document).
  • Path params: propertyId:UUID, guestId:UUID, documentId:UUID
  • Body: none
  • Side effects: Deletes guest document metadata.
  • Auth: Roles: ADMIN, MANAGER
  • Response: 204 Unit
  • Validation/guard checks:
    • 400: Documents can only be deleted for OPEN or CHECKED_IN bookings
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Document not found), 400 (Documents can only be deleted for OPEN or CHECKED_IN bookings), 500 (Failed to delete file)

GET /properties/{propertyId}/guests/{guestId}/documents/{documentId}/file

  • Handler: downloadDocument (src/main/kotlin/com/android/trisolarisserver/controller/guest/GuestDocuments.kt:152)
  • Behavior: Download document.
  • Path params: propertyId:UUID, guestId:UUID, documentId:UUID
  • Query params: token:String? (optional)
  • Body: none
  • Auth: Roles: ADMIN, MANAGER
  • Response: 200 ResponseEntity<FileSystemResource>
  • Common errors: 401 (Invalid token; Missing principal), 403 (Required property role not granted), 404 (Document not found; File missing)

src/main/kotlin/com/android/trisolarisserver/controller/guest/GuestRatings.kt

GET /properties/{propertyId}/guests/{guestId}/ratings

  • Handler: list (src/main/kotlin/com/android/trisolarisserver/controller/guest/GuestRatings.kt:79)
  • Behavior: List resources (list).
  • Path params: propertyId:UUID, guestId:UUID
  • Body: none
  • Auth: Any property member
  • Response: 200 List<GuestRatingResponse>
  • Validation/guard checks:
    • 400: Guest not in property
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Property or guest not found), 400 (Guest not in property)

POST /properties/{propertyId}/guests/{guestId}/ratings

  • Handler: create (src/main/kotlin/com/android/trisolarisserver/controller/guest/GuestRatings.kt:42)
  • Behavior: Create resource (create).
  • Path params: propertyId:UUID, guestId:UUID
  • Body: GuestRatingCreateRequest { bookingId:UUID, score:String, notes:String? (optional) }
  • Auth: Any property member
  • Response: 201 GuestRatingResponse
  • Validation/guard checks:
    • 400: Booking not in property
    • 400: Booking not linked to guest
    • 400: score must be GOOD/OK/TROUBLE or 1/2/3
    • 400: Guest not in property
    • 409: Rating already exists for booking
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Booking not found; Property or guest not found), 400 (Booking not in property; Booking not linked to guest), 409 (Rating already exists for booking)

src/main/kotlin/com/android/trisolarisserver/controller/guest/Guests.kt

GET /properties/{propertyId}/guests/search

  • Handler: search (src/main/kotlin/com/android/trisolarisserver/controller/guest/Guests.kt:75)
  • Behavior: Search.
  • Path params: propertyId:UUID
  • Query params: phone:String? (optional), vehicleNumber:String? (optional)
  • Body: none
  • Auth: Any property member
  • Response: 200 List<GuestResponse>
  • Validation/guard checks:
    • 400: phone or vehicleNumber required
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Property not found), 400 (phone or vehicleNumber required)

GET /properties/{propertyId}/guests/visit-count

  • Handler: getVisitCount (src/main/kotlin/com/android/trisolarisserver/controller/guest/Guests.kt:113)
  • Behavior: Get resource (get visit count).
  • Path params: propertyId:UUID
  • Query params: phone:String (required)
  • Body: none
  • Auth: Any property member
  • Response: 200 GuestVisitCountResponse
  • Validation/guard checks:
    • 400: phone required
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Property not found), 400 (phone required)

GET /properties/{propertyId}/guests/{guestId}

  • Handler: getGuest (src/main/kotlin/com/android/trisolarisserver/controller/guest/Guests.kt:102)
  • Behavior: Get resource (get guest).
  • Path params: propertyId:UUID, guestId:UUID
  • Body: none
  • Auth: Any property member
  • Response: 200 GuestResponse
  • Validation/guard checks:
    • 400: Guest not in property
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Property or guest not found), 400 (Guest not in property)

PUT /properties/{propertyId}/guests/{guestId}

  • Handler: updateGuest (src/main/kotlin/com/android/trisolarisserver/controller/guest/Guests.kt:45)
  • Behavior: Update resource (update guest).
  • Path params: propertyId:UUID, guestId:UUID
  • Body: GuestUpdateRequest { phoneE164:String? (optional), name:String? (optional), nationality:String? (optional), addressText:String? (optional) }
  • Auth: Any property member
  • Response: 200 GuestResponse
  • Validation/guard checks:
    • 400: Guest not in property
    • 409: Phone number already exists
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Property or guest not found), 400 (Guest not in property), 409 (Phone number already exists)

POST /properties/{propertyId}/guests/{guestId}/signature

  • Handler: uploadSignature (src/main/kotlin/com/android/trisolarisserver/controller/guest/Guests.kt:170)
  • Behavior: Upload signature.
  • Path params: propertyId:UUID, guestId:UUID
  • Body: none
  • Auth: Roles: ADMIN, MANAGER
  • Response: 201 GuestResponse
  • Validation/guard checks:
    • 400: File is empty
    • 400: Only SVG allowed
    • 400: Guest not in property
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Property or guest not found), 400 (File is empty; Only SVG allowed)

GET /properties/{propertyId}/guests/{guestId}/signature/file

  • Handler: downloadSignature (src/main/kotlin/com/android/trisolarisserver/controller/guest/Guests.kt:194)
  • Behavior: Download signature.
  • Path params: propertyId:UUID, guestId:UUID
  • Body: none
  • Auth: Any property member
  • Response: 200 ResponseEntity<FileSystemResource>
  • Validation/guard checks:
    • 400: Guest not in property
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Signature not found; Property or guest not found), 400 (Guest not in property)

POST /properties/{propertyId}/guests/{guestId}/vehicles

  • Handler: addVehicle (src/main/kotlin/com/android/trisolarisserver/controller/guest/Guests.kt:130)
  • Behavior: Add vehicle.
  • Path params: propertyId:UUID, guestId:UUID
  • Body: GuestVehicleRequest { vehicleNumber:String, bookingId:UUID }
  • Auth: Any property member
  • Response: 201 GuestResponse
  • Validation/guard checks:
    • 400: Booking not in property
    • 400: Guest not in property
    • 409: Booking linked to different guest
    • 409: Vehicle number already exists
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Booking not found; Property or guest not found), 400 (Booking not in property; Guest not in property), 409 (Booking linked to different guest; Vehicle number already exists)

src/main/kotlin/com/android/trisolarisserver/controller/payment/Charges.kt

GET /properties/{propertyId}/bookings/{bookingId}/charges

  • Handler: list (src/main/kotlin/com/android/trisolarisserver/controller/payment/Charges.kt:80)
  • Behavior: List resources (list).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: none
  • Auth: Any property member
  • Response: 200 List<ChargeResponse>
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Booking not found; Booking not found for property)

POST /properties/{propertyId}/bookings/{bookingId}/charges

  • Handler: create (src/main/kotlin/com/android/trisolarisserver/controller/payment/Charges.kt:44)
  • Behavior: Create resource (create).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: ChargeCreateRequest { type:String, amount:Long, currency:String, occurredAt:String? (optional), notes:String? (optional) }
  • Side effects: Emits booking SSE updates.
  • Auth: Roles: ADMIN, FINANCE, MANAGER
  • Response: 201 ChargeResponse
  • Validation/guard checks:
    • 400: amount must be > 0
    • 400: Invalid timestamp
    • 400: Unknown charge type
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 400 (amount must be > 0; Invalid timestamp)

src/main/kotlin/com/android/trisolarisserver/controller/payment/Payments.kt

GET /properties/{propertyId}/bookings/{bookingId}/payments

  • Handler: list (src/main/kotlin/com/android/trisolarisserver/controller/payment/Payments.kt:86)
  • Behavior: List resources (list).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: none
  • Auth: Any property member
  • Response: 200 List<PaymentResponse>
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Booking not found; Booking not found for property)

POST /properties/{propertyId}/bookings/{bookingId}/payments

  • Handler: create (src/main/kotlin/com/android/trisolarisserver/controller/payment/Payments.kt:47)
  • Behavior: Create resource (create).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: PaymentCreateRequest { amount:Long, method:String? (optional), currency:String? (optional), reference:String? (optional), notes:String? (optional), receivedAt:String? (optional) }
  • Side effects: Emits booking SSE updates.
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 201 PaymentResponse
  • Validation/guard checks:
    • 400: amount must be > 0
    • 400: Invalid timestamp
    • 400: Unknown payment method
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Property not found; Booking not found), 400 (amount must be > 0; Invalid timestamp)

DELETE /properties/{propertyId}/bookings/{bookingId}/payments/{paymentId}

  • Handler: delete (src/main/kotlin/com/android/trisolarisserver/controller/payment/Payments.kt:103)
  • Behavior: Delete resource (delete).
  • Path params: propertyId:UUID, bookingId:UUID, paymentId:UUID
  • Body: none
  • Side effects: Emits booking SSE updates.
  • Auth: Roles: ADMIN
  • Response: 204 Unit
  • Validation/guard checks:
    • 400: Cash payments can only be deleted for OPEN or CHECKED_IN bookings
    • 400: Only CASH payments can be deleted
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 400 (Cash payments can only be deleted for OPEN or CHECKED_IN bookings; Only CASH payments can be deleted)

src/main/kotlin/com/android/trisolarisserver/controller/property/CancellationPolicies.kt

GET /properties/{propertyId}/cancellation-policy

  • Handler: get (src/main/kotlin/com/android/trisolarisserver/controller/property/CancellationPolicies.kt:34)
  • Behavior: Get resource (get).
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Authenticated user (Firebase)
  • Response: 200 CancellationPolicyResponse
  • Common errors: none observed in controller checks

PUT /properties/{propertyId}/cancellation-policy

  • Handler: upsert (src/main/kotlin/com/android/trisolarisserver/controller/property/CancellationPolicies.kt:53)
  • Behavior: Upsert.
  • Path params: propertyId:UUID
  • Body: CancellationPolicyUpsertRequest { freeDaysBeforeCheckin:Int (optional), penaltyMode:String }
  • Auth: Roles: ADMIN
  • Response: 200 CancellationPolicyResponse
  • Validation/guard checks:
    • 400: freeDaysBeforeCheckin must be >= 0
    • 400: Unknown penaltyMode
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Property not found), 400 (freeDaysBeforeCheckin must be >= 0; Unknown penaltyMode)

src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt

GET /properties

  • Handler: listProperties (src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt:92)
  • Behavior: List resources (list properties).
  • Body: none
  • Auth: Authenticated user (Firebase)
  • Response: 200 List<PropertyResponse>
  • Common errors: 401 (User not found)

POST /properties

  • Handler: createProperty (src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt:53)
  • Behavior: Create resource (create property).
  • Body: PropertyCreateRequest { name:String, addressText:String? (optional), timezone:String? (optional), currency:String? (optional), billingCheckinTime:String? (optional), billingCheckoutTime:String? (optional), active:Boolean? (optional), otaAliases:Set? (optional), emailAddresses:Set? (optional), allowedTransportModes:Set? (optional) }
  • Auth: Roles: ADMIN
  • Response: 201 PropertyResponse
  • Validation/guard checks:
    • 400: Unknown transport mode
    • 400: $fieldName must be HH:mm
    • 409: Unable to generate property code
  • Common errors: 401 (User id missing; User not found), 400 (Unknown transport mode; $fieldName must be HH:mm), 409 (Unable to generate property code)

PUT /properties/{propertyId}

  • Handler: updateProperty (src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt:306)
  • Behavior: Update resource (update property).
  • Path params: propertyId:UUID
  • Body: PropertyUpdateRequest { code:String, name:String, addressText:String? (optional), timezone:String? (optional), currency:String? (optional), billingCheckinTime:String? (optional), billingCheckoutTime:String? (optional), active:Boolean? (optional), otaAliases:Set? (optional), emailAddresses:Set? (optional), allowedTransportModes:Set? (optional) }
  • Auth: Roles: ADMIN
  • Response: 200 PropertyResponse
  • Validation/guard checks:
    • 400: Unknown transport mode
    • 400: $fieldName must be HH:mm
    • 409: Property code already exists
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Property not found), 400 (Unknown transport mode; $fieldName must be HH:mm), 409 (Property code already exists)

GET /properties/{propertyId}/billing-policy

  • Handler: getBillingPolicy (src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt:118)
  • Behavior: Get resource (get billing policy).
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Any property member
  • Response: 200 PropertyBillingPolicyResponse
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Property not found)

PUT /properties/{propertyId}/billing-policy

  • Handler: updateBillingPolicy (src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt:135)
  • Behavior: Update resource (update billing policy).
  • Path params: propertyId:UUID
  • Body: PropertyBillingPolicyRequest { billingCheckinTime:String, billingCheckoutTime:String }
  • Auth: Roles: ADMIN
  • Response: 200 PropertyBillingPolicyResponse
  • Validation/guard checks:
    • 400: $fieldName must be HH:mm
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Property not found), 400 ($fieldName must be HH:mm)

GET /properties/{propertyId}/code

  • Handler: getPropertyCode (src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt:105)
  • Behavior: Get resource (get property code).
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Any property member
  • Response: 200 PropertyCodeResponse
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Property not found)

GET /properties/{propertyId}/users

  • Handler: listPropertyUsers (src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt:165)
  • Behavior: List resources (list property users).
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Roles: ADMIN, AGENT, FINANCE, GUIDE, HOUSEKEEPING, MANAGER, STAFF, SUPERVISOR
  • Response: 200 List<PropertyUserResponse>
  • Common errors: 401 (Missing principal), 403 (Property membership required)

DELETE /properties/{propertyId}/users/{userId}

  • Handler: deletePropertyUser (src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt:290)
  • Behavior: Delete resource (delete property user).
  • Path params: propertyId:UUID, userId:UUID
  • Body: none
  • Auth: Roles: ADMIN
  • Response: 204 Unit
  • Common errors: 401 (Missing principal), 403 (Property membership required)

PUT /properties/{propertyId}/users/{userId}/disabled

  • Handler: updatePropertyUserDisabled (src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt:240)
  • Behavior: Update resource (update property user disabled).
  • Path params: propertyId:UUID, userId:UUID
  • Body: PropertyUserDisableRequest { disabled:Boolean }
  • Auth: Roles: ADMIN, AGENT, FINANCE, GUIDE, HOUSEKEEPING, MANAGER, STAFF, SUPERVISOR
  • Response: 200 PropertyUserResponse
  • Common errors: 401 (Missing principal), 403 (Role not allowed; Property membership required), 404 (User not found in property)

PUT /properties/{propertyId}/users/{userId}/roles

  • Handler: upsertPropertyUserRoles (src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt:189)
  • Behavior: Upsert property user roles.
  • Path params: propertyId:UUID, userId:UUID
  • Body: PropertyUserRoleRequest { roles:Set }
  • Auth: Roles: ADMIN, AGENT, MANAGER, STAFF
  • Response: 200 PropertyUserResponse
  • Validation/guard checks:
    • 400: Unknown role
  • Common errors: 401 (Missing principal), 403 (Missing role; Role not allowed), 404 (Property not found; User not found), 400 (Unknown role)

src/main/kotlin/com/android/trisolarisserver/controller/property/PropertyAccessCodes.kt

POST /properties/access-codes/join

  • Handler: joinWithAccessCode (src/main/kotlin/com/android/trisolarisserver/controller/property/PropertyAccessCodes.kt:91)
  • Behavior: Join with access code.
  • Body: PropertyAccessCodeJoinRequest { propertyCode:String? (optional), propertyId:String? (optional), code:String }
  • Auth: Authenticated user (Firebase)
  • Response: 200 PropertyUserResponse
  • Validation/guard checks:
    • 400: Property code required
    • 409: User already a member
  • Common errors: 401 (User not found; Missing principal), 404 (Invalid code; Property not found), 400 (Property code required), 409 (User already a member)

POST /properties/{propertyId}/access-codes

  • Handler: createAccessCode (src/main/kotlin/com/android/trisolarisserver/controller/property/PropertyAccessCodes.kt:45)
  • Behavior: Create resource (create access code).
  • Path params: propertyId:UUID
  • Body: PropertyAccessCodeCreateRequest { roles:Set }
  • Auth: Roles: ADMIN
  • Response: 201 PropertyAccessCodeResponse
  • Validation/guard checks:
    • 400: ADMIN cannot be invited by code
    • 400: At least one role is required
    • 400: Unknown role
    • 409: Unable to generate code, try again
  • Common errors: 401 (User not found; Missing principal), 403 (Property membership required), 404 (Property not found), 400 (ADMIN cannot be invited by code; At least one role is required), 409 (Unable to generate code, try again)

src/main/kotlin/com/android/trisolarisserver/controller/property/UserDirectory.kt

GET /properties/{propertyId}/users/search

  • Handler: searchPropertyUsers (src/main/kotlin/com/android/trisolarisserver/controller/property/UserDirectory.kt:50)
  • Behavior: Search property users.
  • Path params: propertyId:UUID
  • Query params: phone:String? (optional)
  • Body: none
  • Auth: Roles: ADMIN, AGENT, FINANCE, GUIDE, HOUSEKEEPING, MANAGER, STAFF, SUPERVISOR
  • Response: 200 List<PropertyUserDetailsResponse>
  • Common errors: 401 (Missing principal), 403 (Property membership required)

GET /users

  • Handler: listAppUsers (src/main/kotlin/com/android/trisolarisserver/controller/property/UserDirectory.kt:27)
  • Behavior: List resources (list app users).
  • Query params: phone:String? (optional)
  • Body: none
  • Auth: SUPER_ADMIN
  • Response: 200 List<AppUserSummaryResponse>
  • Common errors: 401 (User not found), 403 (Super admin only)

src/main/kotlin/com/android/trisolarisserver/controller/rate/RatePlans.kt

GET /properties/{propertyId}/rate-plans

  • Handler: list (src/main/kotlin/com/android/trisolarisserver/controller/rate/RatePlans.kt:79)
  • Behavior: List resources (list).
  • Path params: propertyId:UUID
  • Query params: roomTypeCode:String? (optional)
  • Body: none
  • Auth: Any property member
  • Response: 200 List<RatePlanResponse>
  • Common errors: 401 (Missing principal), 403 (Property membership required)

POST /properties/{propertyId}/rate-plans

  • Handler: create (src/main/kotlin/com/android/trisolarisserver/controller/rate/RatePlans.kt:51)
  • Behavior: Create resource (create).
  • Path params: propertyId:UUID
  • Body: RatePlanCreateRequest { code:String, name:String, roomTypeCode:String, baseRate:Long, currency:String? (optional) }
  • Auth: Roles: ADMIN, MANAGER
  • Response: 201 RatePlanResponse
  • Validation/guard checks:
    • 409: Rate plan code already exists for room type
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Property not found; Room type not found), 409 (Rate plan code already exists for room type)

DELETE /properties/{propertyId}/rate-plans/{ratePlanId}

  • Handler: delete (src/main/kotlin/com/android/trisolarisserver/controller/rate/RatePlans.kt:114)
  • Behavior: Delete resource (delete).
  • Path params: propertyId:UUID, ratePlanId:UUID
  • Body: none
  • Auth: Roles: ADMIN, MANAGER
  • Response: 204 Unit
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Rate plan not found)

PUT /properties/{propertyId}/rate-plans/{ratePlanId}

  • Handler: update (src/main/kotlin/com/android/trisolarisserver/controller/rate/RatePlans.kt:95)
  • Behavior: Update resource (update).
  • Path params: propertyId:UUID, ratePlanId:UUID
  • Body: RatePlanUpdateRequest { name:String, baseRate:Long, currency:String? (optional) }
  • Auth: Roles: ADMIN, MANAGER
  • Response: 200 RatePlanResponse
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Rate plan not found)

GET /properties/{propertyId}/rate-plans/{ratePlanId}/calendar

  • Handler: listCalendar (src/main/kotlin/com/android/trisolarisserver/controller/rate/RatePlans.kt:170)
  • Behavior: List resources (list calendar).
  • Path params: propertyId:UUID, ratePlanId:UUID
  • Query params: from:String (required), to:String (required)
  • Body: none
  • Auth: Any property member
  • Response: 200 RateCalendarAverageResponse
  • Validation/guard checks:
    • 400: to must be on/after from
    • 400: Invalid date format
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Rate plan not found), 400 (to must be on/after from; Invalid date format)

POST /properties/{propertyId}/rate-plans/{ratePlanId}/calendar

  • Handler: upsertCalendar (src/main/kotlin/com/android/trisolarisserver/controller/rate/RatePlans.kt:129)
  • Behavior: Upsert calendar.
  • Path params: propertyId:UUID, ratePlanId:UUID
  • Body: RateCalendarRangeUpsertRequest { from:String, to:String, rate:Long }
  • Auth: Roles: ADMIN, MANAGER
  • Response: 201 List<RateCalendarResponse>
  • Validation/guard checks:
    • 400: to must be on/after from
    • 400: Invalid date format
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Rate plan not found), 400 (to must be on/after from; Invalid date format)

DELETE /properties/{propertyId}/rate-plans/{ratePlanId}/calendar/{rateDate}

  • Handler: deleteCalendar (src/main/kotlin/com/android/trisolarisserver/controller/rate/RatePlans.kt:206)
  • Behavior: Delete resource (delete calendar).
  • Path params: propertyId:UUID, ratePlanId:UUID, rateDate:String
  • Body: none
  • Auth: Roles: ADMIN, MANAGER
  • Response: 204 Unit
  • Validation/guard checks:
    • 400: Invalid date format
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Rate plan not found), 400 (Invalid date format)

src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayPaymentLinksController.kt

POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/payment-link

  • Handler: createPaymentLink (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayPaymentLinksController.kt:47)
  • Behavior: Create resource (create payment link).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: RazorpayPaymentLinkCreateRequest { amount:Long? (optional), isPartialPaymentAllowed:Boolean? (optional), minAmountForCustomer:Long? (optional), description:String? (optional), expiryDate:String? (optional), successUrl:String? (optional), failureUrl:String? (optional), viaEmail:Boolean? (optional), viaSms:Boolean? (optional) }
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 200 RazorpayPaymentLinkCreateResponse
  • Validation/guard checks:
    • 400: Booking is not active
    • 400: Razorpay settings not configured
    • 400: amount must be > 0
    • 400: Razorpay test keys not configured
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 400 (Booking is not active; Razorpay settings not configured), 502 (Razorpay request failed)

src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayPaymentRequestsController.kt

POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/close

  • Handler: closeRequest (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayPaymentRequestsController.kt:93)
  • Behavior: Close request.
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: RazorpayPaymentRequestCloseRequest { qrId:String? (optional), paymentLinkId:String? (optional) }
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 200 RazorpayPaymentRequestCloseResponse
  • Validation/guard checks:
    • 400: Provide exactly one of qrId or paymentLinkId
    • 400: Razorpay settings not configured
    • 400: Razorpay test keys not configured
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 400 (Provide exactly one of qrId or paymentLinkId; Razorpay settings not configured), 502 (Razorpay close request failed; Razorpay cancel request failed)

GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/requests

  • Handler: listRequests (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayPaymentRequestsController.kt:45)
  • Behavior: List resources (list requests).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: none
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 200 List<RazorpayPaymentRequestResponse>
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property)

src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayQrPayments.kt

GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr

  • Handler: listQr (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayQrPayments.kt:292)
  • Behavior: List resources (list qr).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: none
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 200 List<RazorpayQrRecordResponse>
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property)

POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr

  • Handler: createQr (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayQrPayments.kt:56)
  • Behavior: Create resource (create qr).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: RazorpayQrGenerateRequest { amount:Long? (optional), customerName:String? (optional), customerEmail:String? (optional), customerPhone:String? (optional), expiryMinutes:Int? (optional), expirySeconds:Int? (optional) }
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 200 RazorpayQrGenerateResponse
  • Validation/guard checks:
    • 400: Booking is not active
    • 400: Razorpay settings not configured
    • 400: amount must be > 0
    • 400: Razorpay test keys not configured
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 400 (Booking is not active; Razorpay settings not configured), 502 (Razorpay request failed)

GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/active

  • Handler: getActiveQr (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayQrPayments.kt:157)
  • Behavior: Get resource (get active qr).
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: none
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 200 RazorpayQrGenerateResponse?
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property)

POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/close

  • Handler: closeActiveQr (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayQrPayments.kt:180)
  • Behavior: Close active qr.
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: none
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 200 RazorpayQrGenerateResponse?
  • Validation/guard checks:
    • 400: Razorpay settings not configured
    • 400: Razorpay test keys not configured
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 400 (Razorpay settings not configured; Razorpay test keys not configured), 502 (Razorpay close request failed)

POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/{qrId}/close

  • Handler: closeQrById (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayQrPayments.kt:212)
  • Behavior: Close qr by id.
  • Path params: propertyId:UUID, bookingId:UUID, qrId:String
  • Body: none
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 200 RazorpayQrGenerateResponse?
  • Validation/guard checks:
    • 400: Razorpay settings not configured
    • 400: Razorpay test keys not configured
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 400 (Razorpay settings not configured; Razorpay test keys not configured), 502 (Razorpay close request failed)

GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/{qrId}/events

  • Handler: qrEvents (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayQrPayments.kt:244)
  • Behavior: Qr events.
  • Path params: propertyId:UUID, qrId:String
  • Body: none
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 200 List<RazorpayQrEventResponse>
  • Common errors: 401 (Missing principal), 403 (Required property role not granted)

GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/{qrId}/events/stream

  • Handler: streamQrEvents (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayQrPayments.kt:273)
  • Behavior: Stream events/data (stream qr events).
  • Path params: propertyId:UUID, bookingId:UUID, qrId:String
  • Body: none
  • Side effects: Streams SSE events.
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 200 SseEmitter
  • Common errors: 401 (Missing principal), 403 (Required property role not granted)

src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayRefundsController.kt

POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/refund

  • Handler: refund (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayRefundsController.kt:42)
  • Behavior: Refund.
  • Path params: propertyId:UUID, bookingId:UUID
  • Body: RazorpayRefundRequest { paymentId:UUID? (optional), amount:Long? (optional), notes:String? (optional) }
  • Auth: Roles: ADMIN, FINANCE, MANAGER
  • Response: 200 RazorpayRefundResponse
  • Validation/guard checks:
    • 400: paymentId is required
    • 400: amount must be <= payment amount
    • 400: Payment is missing gateway id
    • 400: Payment is not a Razorpay payment
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Booking not found; Booking not found for property), 400 (paymentId is required; amount must be <= payment amount), 502 (Razorpay refund request failed)

src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayReturnController.kt

POST /properties/{propertyId}/razorpay/return/failure

  • Handler: failure (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayReturnController.kt:22)
  • Behavior: Failure.
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Public/unspecified
  • Response: 204 Unit
  • Common errors: none observed in controller checks

POST /properties/{propertyId}/razorpay/return/success

  • Handler: success (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayReturnController.kt:16)
  • Behavior: Success.
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Public/unspecified
  • Response: 204 Unit
  • Common errors: none observed in controller checks

src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpaySettingsController.kt

GET /properties/{propertyId}/razorpay-settings

  • Handler: getSettings (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpaySettingsController.kt:33)
  • Behavior: Get resource (get settings).
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Roles: ADMIN, MANAGER
  • Response: 200 RazorpaySettingsResponse
  • Common errors: 401 (Missing principal), 403 (Required property role not granted)

PUT /properties/{propertyId}/razorpay-settings

  • Handler: upsertSettings (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpaySettingsController.kt:57)
  • Behavior: Upsert settings.
  • Path params: propertyId:UUID
  • Body: RazorpaySettingsUpsertRequest { keyId:String? (optional), keySecret:String? (optional), webhookSecret:String? (optional), keyIdTest:String? (optional), keySecretTest:String? (optional), webhookSecretTest:String? (optional), isTest:Boolean? (optional), merchantKey:String? (optional), salt32:String? (optional), salt256:String? (optional), useSalt256:Boolean? (optional) }
  • Auth: Roles: ADMIN
  • Response: 200 RazorpaySettingsResponse
  • Validation/guard checks:
    • 400: keyId and keySecret must be provided together
    • 400: keyIdTest and keySecretTest must be provided together
    • 400: keyId/keySecret required
    • 400: keyIdTest/keySecretTest required when isTest=true
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Property not found), 400 (keyId and keySecret must be provided together; keyIdTest and keySecretTest must be provided together)

src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayWebhookCapture.kt

POST /properties/{propertyId}/razorpay/webhook

  • Handler: capture (src/main/kotlin/com/android/trisolarisserver/controller/razorpay/RazorpayWebhookCapture.kt:53)
  • Behavior: Capture.
  • Path params: propertyId:UUID
  • Body: String?
  • Side effects: Emits booking SSE updates.
  • Auth: Public/unspecified
  • Response: 204 Unit
  • Validation/guard checks:
    • 400: Razorpay settings not configured
    • 400: Webhook secret not configured
  • Common errors: 401 (Missing signature; Invalid signature), 404 (Property not found), 400 (Razorpay settings not configured; Webhook secret not configured)

src/main/kotlin/com/android/trisolarisserver/controller/room/RoomAmenities.kt

GET /amenities

  • Handler: listAmenities (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomAmenities.kt:40)
  • Behavior: List resources (list amenities).
  • Body: none
  • Auth: Authenticated user (Firebase)
  • Response: 200 List<AmenityResponse>
  • Common errors: 401 (Missing principal)

POST /amenities

  • Handler: createAmenity (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomAmenities.kt:49)
  • Behavior: Create resource (create amenity).
  • Body: AmenityUpsertRequest { name:String, category:String? (optional), iconKey:String? (optional) }
  • Auth: SUPER_ADMIN
  • Response: 201 AmenityResponse
  • Validation/guard checks:
    • 400: Icon key not found
    • 409: Amenity already exists
  • Common errors: 401 (User not found), 403 (Super admin only), 400 (Icon key not found), 409 (Amenity already exists)

DELETE /amenities/{amenityId}

  • Handler: deleteAmenity (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomAmenities.kt:92)
  • Behavior: Delete resource (delete amenity).
  • Path params: amenityId:UUID
  • Body: none
  • Auth: SUPER_ADMIN
  • Response: 204 Unit
  • Common errors: 401 (User not found), 403 (Super admin only), 404 (Amenity not found)

PUT /amenities/{amenityId}

  • Handler: updateAmenity (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomAmenities.kt:68)
  • Behavior: Update resource (update amenity).
  • Path params: amenityId:UUID
  • Body: AmenityUpsertRequest { name:String, category:String? (optional), iconKey:String? (optional) }
  • Auth: SUPER_ADMIN
  • Response: 200 AmenityResponse
  • Validation/guard checks:
    • 400: Icon key not found
    • 409: Amenity already exists
  • Common errors: 401 (User not found), 403 (Super admin only), 404 (Amenity not found), 400 (Icon key not found), 409 (Amenity already exists)

src/main/kotlin/com/android/trisolarisserver/controller/room/RoomImageTags.kt

GET /image-tags

  • Handler: listTags (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomImageTags.kt:35)
  • Behavior: List resources (list tags).
  • Body: none
  • Auth: Authenticated user (Firebase)
  • Response: 200 List<RoomImageTagResponse>
  • Common errors: none observed in controller checks

POST /image-tags

  • Handler: createTag (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomImageTags.kt:43)
  • Behavior: Create resource (create tag).
  • Body: RoomImageTagUpsertRequest { name:String }
  • Auth: SUPER_ADMIN
  • Response: 201 RoomImageTagResponse
  • Validation/guard checks:
    • 409: Tag already exists
  • Common errors: 401 (User not found), 403 (Super admin only), 409 (Tag already exists)

DELETE /image-tags/{tagId}

  • Handler: deleteTag (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomImageTags.kt:74)
  • Behavior: Delete resource (delete tag).
  • Path params: tagId:UUID
  • Body: none
  • Auth: SUPER_ADMIN
  • Response: 204 Unit
  • Common errors: 401 (User not found), 403 (Super admin only), 404 (Tag not found)

PUT /image-tags/{tagId}

  • Handler: updateTag (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomImageTags.kt:56)
  • Behavior: Update resource (update tag).
  • Path params: tagId:UUID
  • Body: RoomImageTagUpsertRequest { name:String }
  • Auth: SUPER_ADMIN
  • Response: 200 RoomImageTagResponse
  • Validation/guard checks:
    • 409: Tag already exists
  • Common errors: 401 (User not found), 403 (Super admin only), 404 (Tag not found), 409 (Tag already exists)

src/main/kotlin/com/android/trisolarisserver/controller/room/RoomImages.kt

GET /properties/{propertyId}/rooms/{roomId}/images

  • Handler: list (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomImages.kt:55)
  • Behavior: List resources (list).
  • Path params: propertyId:UUID, roomId:UUID
  • Body: none
  • Auth: Authenticated user (Firebase)
  • Response: 200 List<RoomImageResponse>
  • Common errors: 404 (Room not found)

POST /properties/{propertyId}/rooms/{roomId}/images

  • Handler: upload (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomImages.kt:85)
  • Behavior: Upload.
  • Path params: propertyId:UUID, roomId:UUID
  • Query params: file:MultipartFile (required), tagIds:List? (optional)
  • Body: none
  • Auth: Roles: ADMIN, MANAGER
  • Response: 201 RoomImageResponse
  • Validation/guard checks:
    • 400: File is empty
    • 409: Duplicate image for room
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Tag not found; Room not found), 400 (File is empty), 409 (Duplicate image for room)

PUT /properties/{propertyId}/rooms/{roomId}/images/reorder-room

  • Handler: reorderRoomImages (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomImages.kt:199)
  • Behavior: Reorder room images.
  • Path params: propertyId:UUID, roomId:UUID
  • Body: RoomImageReorderRequest { imageIds:List }
  • Auth: Roles: ADMIN, MANAGER
  • Response: 204 Unit
  • Validation/guard checks:
    • 400: Images do not belong to room
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Image not found; Room not found), 400 (Images do not belong to room)

PUT /properties/{propertyId}/rooms/{roomId}/images/reorder-room-type

  • Handler: reorderRoomTypeImages (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomImages.kt:227)
  • Behavior: Reorder room type images.
  • Path params: propertyId:UUID, roomId:UUID
  • Body: RoomImageReorderRequest { imageIds:List }
  • Auth: Roles: ADMIN, MANAGER
  • Response: 204 Unit
  • Validation/guard checks:
    • 400: Images do not belong to room type
    • 400: Images do not belong to property
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Image not found; Room not found), 400 (Images do not belong to room type; Images do not belong to property)

DELETE /properties/{propertyId}/rooms/{roomId}/images/{imageId}

  • Handler: delete (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomImages.kt:129)
  • Behavior: Delete resource (delete).
  • Path params: propertyId:UUID, roomId:UUID, imageId:UUID
  • Body: none
  • Auth: Roles: ADMIN, MANAGER
  • Response: 204 Unit
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Image not found; Room not found), 500 (Failed to delete image files)

GET /properties/{propertyId}/rooms/{roomId}/images/{imageId}/file

  • Handler: file (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomImages.kt:257)
  • Behavior: File.
  • Path params: propertyId:UUID, roomId:UUID, imageId:UUID
  • Query params: size:String (optional)
  • Body: none
  • Auth: Any property member
  • Response: 200 ResponseEntity<FileSystemResource>
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Image not found; File missing)

PUT /properties/{propertyId}/rooms/{roomId}/images/{imageId}/tags

  • Handler: updateTags (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomImages.kt:180)
  • Behavior: Update resource (update tags).
  • Path params: propertyId:UUID, roomId:UUID, imageId:UUID
  • Body: RoomImageTagUpdateRequest { tagIds:Set }
  • Auth: Roles: ADMIN, MANAGER
  • Response: 204 Unit
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Image not found; Tag not found)

src/main/kotlin/com/android/trisolarisserver/controller/room/RoomStays.kt

GET /properties/{propertyId}/room-stays/active

  • Handler: listActiveRoomStays (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomStays.kt:42)
  • Behavior: List resources (list active room stays).
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Roles: ADMIN, AGENT, FINANCE, GUIDE, HOUSEKEEPING, MANAGER, STAFF, SUPERVISOR
  • Response: 200 List<ActiveRoomStayResponse>
  • Common errors: 401 (Missing principal), 403 (Agents cannot view active stays; Property membership required)

POST /properties/{propertyId}/room-stays/{roomStayId}/void

  • Handler: voidRoomStay (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomStays.kt:78)
  • Behavior: Void room stay.
  • Path params: propertyId:UUID, roomStayId:UUID
  • Body: RoomStayVoidRequest { reason:String? (optional) }
  • Side effects: Writes room-stay audit log.
  • Auth: Roles: ADMIN, MANAGER, STAFF
  • Response: 200 Unit
  • Validation/guard checks:
    • 409: Cannot void checked-out room stay
  • Common errors: 401 (Missing principal), 403 (Missing role; Cannot void stay after first payment), 404 (Room stay not found for property), 409 (Cannot void checked-out room stay)

src/main/kotlin/com/android/trisolarisserver/controller/room/RoomTypeImages.kt

GET /properties/{propertyId}/room-types/{roomTypeCode}/images

  • Handler: listByRoomType (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomTypeImages.kt:29)
  • Behavior: List resources (list by room type).
  • Path params: propertyId:UUID, roomTypeCode:String
  • Body: none
  • Auth: Public/unspecified
  • Response: 200 List<RoomImageResponse>
  • Common errors: 404 (Room type not found)

src/main/kotlin/com/android/trisolarisserver/controller/room/RoomTypes.kt

GET /properties/{propertyId}/room-types

  • Handler: listRoomTypes (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomTypes.kt:49)
  • Behavior: List resources (list room types).
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Any property member
  • Response: 200 List<RoomTypeResponse>
  • Common errors: 401 (Missing principal), 403 (Property membership required)

POST /properties/{propertyId}/room-types

  • Handler: createRoomType (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomTypes.kt:107)
  • Behavior: Create resource (create room type).
  • Path params: propertyId:UUID
  • Body: RoomTypeUpsertRequest { code:String, name:String, baseOccupancy:Int? (optional), maxOccupancy:Int? (optional), sqFeet:Int? (optional), bathroomSqFeet:Int? (optional), defaultRate:Long? (optional), active:Boolean? (optional), otaAliases:Set? (optional), amenityIds:Set? (optional) }
  • Auth: Roles: ADMIN, MANAGER
  • Response: 201 RoomTypeResponse
  • Validation/guard checks:
    • 409: Room type code already exists for property
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Property not found; Amenity not found), 409 (Room type code already exists for property)

GET /properties/{propertyId}/room-types/{roomTypeCode}/rate

  • Handler: resolveRate (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomTypes.kt:60)
  • Behavior: Resolve rate.
  • Path params: propertyId:UUID, roomTypeCode:String
  • Query params: date:String (required), ratePlanCode:String? (optional)
  • Body: none
  • Auth: Any property member
  • Response: 200 RateResolveResponse
  • Validation/guard checks:
    • 400: Rate plan not for room type
    • 400: Invalid date format
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Property not found; Room type not found), 400 (Rate plan not for room type; Invalid date format)

DELETE /properties/{propertyId}/room-types/{roomTypeId}

  • Handler: deleteRoomType (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomTypes.kt:189)
  • Behavior: Delete resource (delete room type).
  • Path params: propertyId:UUID, roomTypeId:UUID
  • Body: none
  • Auth: Roles: ADMIN, MANAGER
  • Response: 204 Unit
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Room type not found)

PUT /properties/{propertyId}/room-types/{roomTypeId}

  • Handler: updateRoomType (src/main/kotlin/com/android/trisolarisserver/controller/room/RoomTypes.kt:153)
  • Behavior: Update resource (update room type).
  • Path params: propertyId:UUID, roomTypeId:UUID
  • Body: RoomTypeUpsertRequest { code:String, name:String, baseOccupancy:Int? (optional), maxOccupancy:Int? (optional), sqFeet:Int? (optional), bathroomSqFeet:Int? (optional), defaultRate:Long? (optional), active:Boolean? (optional), otaAliases:Set? (optional), amenityIds:Set? (optional) }
  • Auth: Roles: ADMIN, MANAGER
  • Response: 200 RoomTypeResponse
  • Validation/guard checks:
    • 409: Room type code already exists for property
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Room type not found; Amenity not found), 409 (Room type code already exists for property)

src/main/kotlin/com/android/trisolarisserver/controller/room/Rooms.kt

GET /properties/{propertyId}/rooms

  • Handler: listRooms (src/main/kotlin/com/android/trisolarisserver/controller/room/Rooms.kt:66)
  • Behavior: List resources (list rooms).
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Roles: ADMIN, AGENT, FINANCE, HOUSEKEEPING, MANAGER, STAFF
  • Response: 200 List<RoomResponse>
  • Common errors: 401 (Missing principal), 403 (Property membership required)

POST /properties/{propertyId}/rooms

  • Handler: createRoom (src/main/kotlin/com/android/trisolarisserver/controller/room/Rooms.kt:278)
  • Behavior: Create resource (create room).
  • Path params: propertyId:UUID
  • Body: RoomUpsertRequest { roomNumber:Int, floor:Int? (optional), roomTypeCode:String, hasNfc:Boolean, active:Boolean, maintenance:Boolean, notes:String? (optional) }
  • Side effects: Emits room board SSE updates.
  • Auth: Roles: ADMIN
  • Response: 201 RoomResponse
  • Validation/guard checks:
    • 400: roomTypeCode required
    • 409: Room number already exists for property
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Property not found; Room type not found), 400 (roomTypeCode required), 409 (Room number already exists for property)

GET /properties/{propertyId}/rooms/availability

  • Handler: roomAvailability (src/main/kotlin/com/android/trisolarisserver/controller/room/Rooms.kt:126)
  • Behavior: Room availability.
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Any property member
  • Response: 200 List<RoomAvailabilityResponse>
  • Common errors: 401 (Missing principal), 403 (Property membership required)

GET /properties/{propertyId}/rooms/availability-range

  • Handler: roomAvailabilityRange (src/main/kotlin/com/android/trisolarisserver/controller/room/Rooms.kt:184)
  • Behavior: Room availability range.
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Any property member
  • Response: 200 List<RoomAvailabilityRangeResponse>
  • Validation/guard checks:
    • 400: Invalid date range
    • 400: Invalid date format
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Property not found), 400 (Invalid date range; Invalid date format)

GET /properties/{propertyId}/rooms/available

  • Handler: availableRooms (src/main/kotlin/com/android/trisolarisserver/controller/room/Rooms.kt:147)
  • Behavior: Available rooms.
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Authenticated user (Firebase)
  • Response: 200 List<RoomResponse>
  • Common errors: none observed in controller checks

GET /properties/{propertyId}/rooms/available-range-with-rate

  • Handler: availableRoomsWithRate (src/main/kotlin/com/android/trisolarisserver/controller/room/Rooms.kt:221)
  • Behavior: Available rooms with rate.
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Any property member
  • Response: 200 List<RoomAvailabilityWithRateResponse>
  • Validation/guard checks:
    • 400: Invalid date range
    • 400: Invalid date format
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Property not found), 400 (Invalid date range; Invalid date format)

GET /properties/{propertyId}/rooms/board

  • Handler: roomBoard (src/main/kotlin/com/android/trisolarisserver/controller/room/Rooms.kt:86)
  • Behavior: Room board.
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Roles: ADMIN, AGENT, FINANCE, HOUSEKEEPING, MANAGER, STAFF
  • Response: 200 List<RoomBoardResponse>
  • Common errors: 401 (Missing principal), 403 (Property membership required)

GET /properties/{propertyId}/rooms/board/stream

  • Handler: roomBoardStream (src/main/kotlin/com/android/trisolarisserver/controller/room/Rooms.kt:114)
  • Behavior: Room board stream.
  • Path params: propertyId:UUID
  • Body: none
  • Side effects: Streams SSE events.
  • Auth: Any property member
  • Response: 200 SseEmitter
  • Common errors: 401 (Missing principal), 403 (Property membership required)

GET /properties/{propertyId}/rooms/by-type/{roomTypeCode}

  • Handler: roomsByType (src/main/kotlin/com/android/trisolarisserver/controller/room/Rooms.kt:160)
  • Behavior: Rooms by type.
  • Path params: propertyId:UUID, roomTypeCode:String
  • Body: none
  • Auth: Roles: ADMIN, AGENT, FINANCE, HOUSEKEEPING, MANAGER, STAFF
  • Response: 200 List<RoomResponse>
  • Common errors: 404 (Room type not found)

DELETE /properties/{propertyId}/rooms/{roomId}

  • Handler: deleteRoom (src/main/kotlin/com/android/trisolarisserver/controller/room/Rooms.kt:367)
  • Behavior: Delete resource (delete room).
  • Path params: propertyId:UUID, roomId:UUID
  • Body: none
  • Side effects: Emits room board SSE updates.
  • Auth: Roles: ADMIN, MANAGER
  • Response: 204 Unit
  • Validation/guard checks:
    • 409: Cannot delete room with stays
  • Common errors: 401 (Missing principal), 403 (Property membership required), 404 (Room not found for property), 409 (Cannot delete room with stays), 500 (Failed to delete room image files)

PUT /properties/{propertyId}/rooms/{roomId}

  • Handler: updateRoom (src/main/kotlin/com/android/trisolarisserver/controller/room/Rooms.kt:323)
  • Behavior: Update resource (update room).
  • Path params: propertyId:UUID, roomId:UUID
  • Body: RoomUpsertRequest { roomNumber:Int, floor:Int? (optional), roomTypeCode:String, hasNfc:Boolean, active:Boolean, maintenance:Boolean, notes:String? (optional) }
  • Side effects: Emits room board SSE updates.
  • Auth: Roles: ADMIN
  • Response: 200 RoomResponse
  • Validation/guard checks:
    • 400: roomTypeCode required
    • 409: Room number already exists for property
  • Common errors: 401 (Missing principal), 403 (Required property role not granted), 404 (Room not found for property; Room type not found), 400 (roomTypeCode required), 409 (Room number already exists for property)

src/main/kotlin/com/android/trisolarisserver/controller/system/Health.kt

GET /

  • Handler: root (src/main/kotlin/com/android/trisolarisserver/controller/system/Health.kt:14)
  • Behavior: Root.
  • Body: none
  • Auth: Public/unspecified
  • Response: 200 Map<String, String>
  • Common errors: none observed in controller checks

GET /health

  • Handler: health (src/main/kotlin/com/android/trisolarisserver/controller/system/Health.kt:9)
  • Behavior: Health.
  • Body: none
  • Auth: Public/unspecified
  • Response: 200 Map<String, String>
  • Common errors: none observed in controller checks

src/main/kotlin/com/android/trisolarisserver/controller/transport/TransportModes.kt

GET /properties/{propertyId}/transport-modes

  • Handler: list (src/main/kotlin/com/android/trisolarisserver/controller/transport/TransportModes.kt:26)
  • Behavior: List resources (list).
  • Path params: propertyId:UUID
  • Body: none
  • Auth: Any property member
  • Response: 200 List<TransportModeStatusResponse>
  • Common errors: 401 (Missing principal), 403 (Property membership required)