1576 lines
76 KiB
Markdown
1576 lines
76 KiB
Markdown
# 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<BookingCheckInStayRequest>, 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<String>? (optional), emailAddresses:Set<String>? (optional), allowedTransportModes:Set<String>? (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<String>? (optional), emailAddresses:Set<String>? (optional), allowedTransportModes:Set<String>? (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<String> }
|
|
- 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<String> }
|
|
- 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<UUID>? (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<UUID> }
|
|
- 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<UUID> }
|
|
- 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<UUID> }
|
|
- 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<String>? (optional), amenityIds:Set<UUID>? (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<String>? (optional), amenityIds:Set<UUID>? (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)
|