From 5254254b6dc476ca2754dace1f8f4f7a8f2621cb Mon Sep 17 00:00:00 2001 From: androidlover5842 Date: Wed, 4 Feb 2026 13:08:13 +0530 Subject: [PATCH] docs: rewrite API docs in txt endpoint-by-endpoint format --- docs/API_MANUAL.md | 622 --------- docs/API_REFERENCE.txt | 3023 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 3023 insertions(+), 622 deletions(-) delete mode 100644 docs/API_MANUAL.md create mode 100644 docs/API_REFERENCE.txt diff --git a/docs/API_MANUAL.md b/docs/API_MANUAL.md deleted file mode 100644 index 872a1a7..0000000 --- a/docs/API_MANUAL.md +++ /dev/null @@ -1,622 +0,0 @@ -# Trisolaris Server API Manual (Manual, No Script) - -Last updated: 2026-02-04 -Source: current Kotlin controllers in this repo. - -## Global rules - -- Base API domain: `api.hoteltrisolaris.in` -- Auth: Firebase bearer token (`MyPrincipal`) for all non-public endpoints. -- Super admin bypass: property membership/role checks are bypassed by `superAdmin=true` (via `PropertyAccess`). -- Global API error shape: - ```json - { - "timestamp": "...", - "status": 400, - "error": "Bad Request", - "message": "...", - "path": "/..." - } - ``` -- Common auth/permission errors: - - `401 Unauthorized`: missing principal / user not found - - `403 Forbidden`: missing membership/role - -## Public endpoints (no auth required) - -- `GET /` -- `GET /health` -- `GET /auth/*` -- `GET /properties/{propertyId}/rooms/available` -- `GET /properties/{propertyId}/rooms/by-type/{roomTypeCode}` -- `GET /properties/{propertyId}/room-types` -- `GET /properties/{propertyId}/room-types/{roomTypeCode}/images` -- `GET /properties/{propertyId}/rooms/{roomId}/images` -- `GET /properties/{propertyId}/rooms/{roomId}/images/{imageId}/file` -- `GET /properties/{propertyId}/guests/{guestId}/documents/{documentId}/file` (or token-based access) -- `GET /properties/{propertyId}/cancellation-policy` -- `GET /image-tags` -- `GET /icons/png` -- `GET /icons/png/{filename}` -- `POST /properties/{propertyId}/razorpay/webhook` -- `POST /properties/{propertyId}/razorpay/return/success` -- `POST /properties/{propertyId}/razorpay/return/failure` - -## Core storage map - -- Property + config: `property`, `property_email_address`, `property_email_alias`, `property_transport_mode` -- Users + membership: `app_user`, `property_user`, `property_user_role`, `property_access_code`, `property_access_code_role` -- Room inventory: `room_type`, `room_type_alias`, `room_type_amenity_link`, `room`, `room_amenity` -- Stays + cards: `room_stay`, `room_stay_audit_log`, `issued_card`, `property_card_counter` -- Booking + billing: `booking`, `booking_room_request`, `booking_billing_policy_audit_log`, `charge`, `payment` -- Guest data: `guest`, `guest_vehicle`, `guest_rating`, `guest_document` -- Rates: `rate_plan`, `rate_calendar` -- Email ingest: `inbound_email` -- Room media: `room_image`, `room_image_tag`, `room_image_tag_link` -- Razorpay: `razorpay_settings`, `razorpay_qr_request`, `razorpay_payment_link_request`, `razorpay_payment_attempt`, `razorpay_webhook_log` -- File storage roots: - - documents/signatures: `/home/androidlover5842/docs` - - emails: `/home/androidlover5842/docs/emails` - - room images: `/home/androidlover5842/docs/rooms` - - icons: `/home/androidlover5842/docs/icons/png` - ---- - -## 1) Auth APIs - -- `POST /auth/verify` - - What it does: resolves Firebase principal (creates app user if missing), returns user + property memberships. - - Access: public. - - Stores data: may insert/update `app_user`; reads `property_user`. -- `GET /auth/me` - - What it does: same shape as verify. - - Access: public. - - Stores data: may create `app_user` if resolver is used. -- `PUT /auth/me` - - Request: `{ "name": "..." }` - - What it does: updates current user name. - - Access: authenticated user. - - Stores data: updates `app_user.name`. - -## 2) System + Static assets - -- `GET /health` / `GET /` - - What it does: health payload with build identifier. - - Access: public. - - Stores data: none. -- `GET /icons/png` - - What it does: lists PNG filenames in icon root. - - Access: public. - - Stores data: reads filesystem only. -- `GET /icons/png/{filename}` - - What it does: serves icon PNG. - - Access: public. - - Stores data: reads filesystem only. - -## 3) Property + User management - -- `POST /properties` - - Request: `PropertyCreateRequest`. - - Access: authenticated user. - - Stores data: inserts `property` (+ email/alias/transport collections); inserts `property_user` with `ADMIN`. -- `GET /properties` - - What it does: list properties (all for super admin, memberships for others). - - Access: authenticated user. - - Stores data: reads `property`, `property_user`. -- `GET /properties/{propertyId}/code` - - Access: property member. - - Stores data: reads `property.code`. -- `PUT /properties/{propertyId}` - - Request: `PropertyUpdateRequest`. - - Access: `ADMIN`. - - Stores data: updates `property` and its collection tables. -- `GET /properties/{propertyId}/billing-policy` - - Access: property member. - - Stores data: reads `property.billing_checkin_time`, `property.billing_checkout_time`. -- `PUT /properties/{propertyId}/billing-policy` - - Request: `PropertyBillingPolicyRequest`. - - Access: `ADMIN`. - - Stores data: updates `property` billing policy. -- `GET /properties/{propertyId}/users` - - Access: `ADMIN`/`MANAGER`. - - Stores data: reads `property_user`, `app_user`. -- `PUT /properties/{propertyId}/users/{userId}/roles` - - Request: `PropertyUserRoleRequest`. - - Access: super admin / `ADMIN` / `MANAGER` (role-limited by hierarchy). - - Stores data: upserts `property_user` + `property_user_role`. -- `PUT /properties/{propertyId}/users/{userId}/disabled` - - Request: `PropertyUserDisableRequest`. - - Access: hierarchy-based. - - Stores data: updates `property_user.is_disabled`. -- `DELETE /properties/{propertyId}/users/{userId}` - - Access: `ADMIN`. - - Stores data: deletes `property_user` membership. - -### Access codes + directory - -- `POST /properties/{propertyId}/access-codes` - - Request: `PropertyAccessCodeCreateRequest` (`roles`, no `ADMIN`). - - Access: `ADMIN`. - - Stores data: inserts `property_access_code` + `property_access_code_role` (1-minute expiry). -- `POST /properties/access-codes/join` - - Request: `PropertyAccessCodeJoinRequest` (`propertyCode` + `code`). - - Access: authenticated. - - Stores data: inserts `property_user`; marks `property_access_code.used_at/used_by`. -- `GET /users` - - Query: optional `phone`. - - Access: super admin only. - - Stores data: reads `app_user`. -- `GET /properties/{propertyId}/users/search` - - Query: optional `phone`. - - Access: `ADMIN`. - - Stores data: reads `property_user`, `app_user`. - -### Cancellation policy + transport modes - -- `GET /properties/{propertyId}/cancellation-policy` - - Access: public. - - Stores data: reads `property_cancellation_policy` (or default response). -- `PUT /properties/{propertyId}/cancellation-policy` - - Request: `CancellationPolicyUpsertRequest`. - - Access: `ADMIN`. - - Stores data: upserts `property_cancellation_policy`. -- `GET /properties/{propertyId}/transport-modes` - - Access: property member. - - Stores data: reads `property.allowedTransportModes`. - -## 4) Room amenities + image tags - -- `GET /amenities` - - Access: authenticated. - - Stores data: reads `room_amenity`. -- `POST /amenities` - - Request: `AmenityUpsertRequest`. - - Access: super admin only. - - Stores data: inserts `room_amenity`. -- `PUT /amenities/{amenityId}` - - Request: `AmenityUpsertRequest`. - - Access: super admin only. - - Stores data: updates `room_amenity`. -- `DELETE /amenities/{amenityId}` - - Access: super admin only. - - Stores data: deletes `room_amenity`; removes links from `room_type_amenity_link`. - -- `GET /image-tags` - - Access: public. - - Stores data: reads `room_image_tag`. -- `POST /image-tags` - - Request: `RoomImageTagUpsertRequest`. - - Access: super admin only. - - Stores data: inserts `room_image_tag`. -- `PUT /image-tags/{tagId}` - - Request: `RoomImageTagUpsertRequest`. - - Access: super admin only. - - Stores data: updates `room_image_tag`. -- `DELETE /image-tags/{tagId}` - - Access: super admin only. - - Stores data: deletes links from `room_image_tag_link`, deletes `room_image_tag`. - -## 5) Room types - -- `GET /properties/{propertyId}/room-types` - - Access: public (or member when auth present). - - Stores data: reads `room_type` + alias/amenity links. -- `POST /properties/{propertyId}/room-types` - - Request: `RoomTypeUpsertRequest`. - - Access: `ADMIN`/`MANAGER`. - - Stores data: inserts `room_type`, `room_type_alias`, `room_type_amenity_link`. -- `PUT /properties/{propertyId}/room-types/{roomTypeId}` - - Request: `RoomTypeUpsertRequest`. - - Access: `ADMIN`/`MANAGER`. - - Stores data: updates `room_type` and links. -- `DELETE /properties/{propertyId}/room-types/{roomTypeId}` - - Access: `ADMIN`/`MANAGER`. - - Stores data: soft delete by setting `room_type.is_active=false`. -- `GET /properties/{propertyId}/room-types/{roomTypeCode}/rate?date=...&ratePlanCode=...` - - Access: public/member. - - Stores data: reads `room_type`, `rate_plan`, `rate_calendar`. - -## 6) Rooms + availability + board - -- `GET /properties/{propertyId}/rooms` - - Access: property member (agents see only free sellable rooms). - - Stores data: reads `room`, active stays in `room_stay`, temp cards in `issued_card`. -- `POST /properties/{propertyId}/rooms` - - Request: `RoomUpsertRequest`. - - Access: `ADMIN`. - - Stores data: inserts `room`. -- `PUT /properties/{propertyId}/rooms/{roomId}` - - Request: `RoomUpsertRequest`. - - Access: `ADMIN`. - - Stores data: updates `room`. -- `DELETE /properties/{propertyId}/rooms/{roomId}` - - Access: `ADMIN`/`MANAGER`. - - Stores data: deletes room image files + `room_image` rows, then deletes `room` (blocked if any `room_stay` exists). - -- `GET /properties/{propertyId}/rooms/board` - - Access: member (agent filtered to FREE). - - Stores data: reads `room`, active occupancy from `room_stay`. -- `GET /properties/{propertyId}/rooms/board/stream` - - Access: member. - - Stores data: no writes; SSE from derived room board events. -- `GET /properties/{propertyId}/rooms/availability` - - Access: member. - - Stores data: reads `room`, `room_stay`. -- `GET /properties/{propertyId}/rooms/available` - - Access: public. - - Stores data: reads `room`, `room_stay`, `issued_card`. -- `GET /properties/{propertyId}/rooms/by-type/{roomTypeCode}?availableOnly=true|false` - - Access: public. - - Stores data: reads `room_type`, `room`, `room_stay`, `issued_card`. -- `GET /properties/{propertyId}/rooms/availability-range?from=YYYY-MM-DD&to=YYYY-MM-DD` - - Access: member. - - Stores data: reads `room`, `room_stay`, `property.timezone`. -- `GET /properties/{propertyId}/rooms/available-range-with-rate?from=...&to=...&ratePlanCode=...` - - Access: member. - - Stores data: reads `room`, `room_stay`, `rate_plan`, `rate_calendar`, `property`. - -## 7) Room images - -- `GET /properties/{propertyId}/rooms/{roomId}/images` - - Access: public. - - Stores data: reads `room_image`; deletes missing-file rows; reads filesystem. -- `POST /properties/{propertyId}/rooms/{roomId}/images` - - Multipart: file + optional `tagIds`. - - Access: `ADMIN`/`MANAGER`. - - Stores data: writes files under `/docs/rooms`; inserts `room_image` + `room_image_tag_link`. -- `DELETE /properties/{propertyId}/rooms/{roomId}/images/{imageId}` - - Access: `ADMIN`/`MANAGER`. - - Stores data: deletes files + `room_image`; reorders sort fields. -- `PUT /properties/{propertyId}/rooms/{roomId}/images/{imageId}/tags` - - Request: `RoomImageTagUpdateRequest`. - - Access: `ADMIN`/`MANAGER`. - - Stores data: updates `room_image_tag_link`. -- `PUT /properties/{propertyId}/rooms/{roomId}/images/reorder-room` - - Request: `RoomImageReorderRequest`. - - Access: `ADMIN`/`MANAGER`. - - Stores data: updates `room_image.sort_order`. -- `PUT /properties/{propertyId}/rooms/{roomId}/images/reorder-room-type` - - Request: `RoomImageReorderRequest`. - - Access: `ADMIN`/`MANAGER`. - - Stores data: updates `room_image.room_type_sort_order`. -- `GET /properties/{propertyId}/rooms/{roomId}/images/{imageId}/file?size=full|thumb` - - Access: public/member. - - Stores data: reads filesystem + `room_image` metadata. -- `GET /properties/{propertyId}/room-types/{roomTypeCode}/images` - - Access: public. - - Stores data: reads `room_image`; prunes missing-file rows. - -## 8) Room stays + cards - -- `GET /properties/{propertyId}/room-stays/active` - - Access: member except AGENT-only users. - - Stores data: reads `room_stay`, `booking`, `guest`, `room`. -- `POST /properties/{propertyId}/room-stays/{roomStayId}/void` - - Request: `RoomStayVoidRequest`. - - Access: `ADMIN`/`MANAGER`/`STAFF` (staff blocked after first booking payment). - - Stores data: updates `room_stay` (`is_voided`, `to_at`), inserts `room_stay_audit_log`, may update `booking` to `CHECKED_OUT`. - -### Issued cards (room stay) - -- `POST /properties/{propertyId}/room-stays/{roomStayId}/cards/prepare` - - Request: `CardPrepareRequest`. - - Access: `ADMIN`/`MANAGER`. - - Stores data: increments `property_card_counter`; returns encoded payload only. -- `POST /properties/{propertyId}/room-stays/{roomStayId}/cards` - - Request: `IssueCardRequest`. - - Access: `ADMIN`/`MANAGER`. - - Stores data: inserts `issued_card`. -- `GET /properties/{propertyId}/room-stays/{roomStayId}/cards` - - Access: `STAFF`/`ADMIN`/`MANAGER`/`SUPERVISOR`. - - Stores data: reads `issued_card`. -- `POST /properties/{propertyId}/room-stays/cards/{cardIndex}/revoke` - - Access: ADMIN for regular cards; ADMIN/MANAGER for temp cards. - - Stores data: updates `issued_card.revoked_at` and `expires_at`. -- `GET /properties/{propertyId}/room-stays/cards/{cardIndex}` - - Access: `ADMIN`/`MANAGER`. - - Stores data: reads `issued_card`. - -### Temporary room cards - -- `POST /properties/{propertyId}/rooms/{roomId}/cards/prepare-temp` - - Access: `ADMIN`/`MANAGER`. - - Stores data: increments `property_card_counter`; returns payload only. -- `POST /properties/{propertyId}/rooms/{roomId}/cards/temp` - - Request: `IssueTempCardRequest`. - - Access: `ADMIN`/`MANAGER`. - - Stores data: inserts temp `issued_card` (7-minute expiry). - -## 9) Booking APIs - -- `POST /properties/{propertyId}/bookings` - - Request: `BookingCreateRequest`. - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: inserts `booking`; creates placeholder `guest` if needed. -- `GET /properties/{propertyId}/bookings?status=...` - - Access: `ADMIN`/`MANAGER`/`STAFF`/`HOUSEKEEPING`/`FINANCE`. - - Stores data: reads `booking`, `room_stay`, `charge`, `payment`. -- `GET /properties/{propertyId}/bookings/{bookingId}` - - Access: same as list. - - Stores data: reads booking snapshot from `booking`, `guest`, `room_stay`, `guest_vehicle`, `charge`, `payment`. -- `GET /properties/{propertyId}/bookings/{bookingId}/stream` - - Access: same as list. - - Stores data: no writes; SSE booking event stream. -- `POST /properties/{propertyId}/bookings/{bookingId}/link-guest` - - Request: `BookingLinkGuestRequest`. - - Access: property member. - - Stores data: updates `booking.primary_guest_id`; may delete placeholder `guest` when safe. -- `POST /properties/{propertyId}/bookings/{bookingId}/check-in/bulk` - - Request: `BookingBulkCheckInRequest`. - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: inserts `room_stay`; updates `booking` to `CHECKED_IN`; may fulfill `booking_room_request`. -- `POST /properties/{propertyId}/bookings/{bookingId}/expected-dates` - - Request: `BookingExpectedDatesUpdateRequest`. - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: updates `booking.expected_checkin_at` / `booking.expected_checkout_at`. -- `POST /properties/{propertyId}/bookings/{bookingId}/billing-policy` - - Request: `BookingBillingPolicyUpdateRequest`. - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: updates `booking.billing_*`; inserts `booking_billing_policy_audit_log` when changed. -- `POST /properties/{propertyId}/bookings/{bookingId}/check-out` - - Request: `BookingCheckOutRequest`. - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: closes active `room_stay` rows (`to_at`), inserts `room_stay_audit_log`, updates `booking` to `CHECKED_OUT`. -- `POST /properties/{propertyId}/bookings/{bookingId}/room-stays/{roomStayId}/check-out` - - Request: `BookingCheckOutRequest`. - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: closes specific `room_stay`, inserts audit log, may auto-close `booking`. -- `POST /properties/{propertyId}/bookings/{bookingId}/cancel` - - Request: `BookingCancelRequest`. - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: updates `booking.status=CANCELLED`; may insert penalty row in `charge`. -- `POST /properties/{propertyId}/bookings/{bookingId}/no-show` - - Request: `BookingNoShowRequest`. - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: updates `booking.status=NO_SHOW`; may insert penalty row in `charge`. - -### Room requests + booking balance - -- `POST /properties/{propertyId}/bookings/{bookingId}/room-requests` - - Request: `BookingRoomRequestCreateRequest`. - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: inserts `booking_room_request`. -- `GET /properties/{propertyId}/bookings/{bookingId}/room-requests` - - Access: `ADMIN`/`MANAGER`/`STAFF`/`HOUSEKEEPING`/`FINANCE`. - - Stores data: reads `booking_room_request`. -- `DELETE /properties/{propertyId}/bookings/{bookingId}/room-requests/{requestId}` - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: sets `booking_room_request.status=CANCELLED`. -- `GET /properties/{propertyId}/bookings/{bookingId}/balance` - - Access: property member. - - Stores data: reads `room_stay`, `charge`, `payment` and returns computed ledger balance. - -## 10) Charges + Payments APIs - -- `POST /properties/{propertyId}/bookings/{bookingId}/charges` - - Request: `ChargeCreateRequest`. - - Access: `ADMIN`/`MANAGER`/`FINANCE`. - - Stores data: inserts `charge`. -- `GET /properties/{propertyId}/bookings/{bookingId}/charges` - - Access: property member. - - Stores data: reads `charge`. - -- `POST /properties/{propertyId}/bookings/{bookingId}/payments` - - Request: `PaymentCreateRequest`. - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: inserts `payment`. -- `GET /properties/{propertyId}/bookings/{bookingId}/payments` - - Access: property member. - - Stores data: reads `payment`. -- `DELETE /properties/{propertyId}/bookings/{bookingId}/payments/{paymentId}` - - Access: `ADMIN` (super admin allowed through bypass). - - Stores data: deletes `payment` only when method is CASH and booking is OPEN/CHECKED_IN. - -## 11) Guest APIs - -- `PUT /properties/{propertyId}/guests/{guestId}` - - Request: `GuestUpdateRequest`. - - Access: property member. - - Stores data: updates `guest`. -- `GET /properties/{propertyId}/guests/search?phone=...|vehicleNumber=...` - - Access: property member. - - Stores data: reads `guest`, `guest_vehicle`, `guest_rating`. -- `GET /properties/{propertyId}/guests/{guestId}` - - Access: property member. - - Stores data: reads `guest`, `guest_vehicle`, `guest_rating`. -- `GET /properties/{propertyId}/guests/visit-count?phone=...` - - Access: property member. - - Stores data: reads `guest`, booking count from `booking`. -- `POST /properties/{propertyId}/guests/{guestId}/vehicles` - - Request: `GuestVehicleRequest`. - - Access: property member. - - Stores data: inserts/updates `guest_vehicle`. -- `POST /properties/{propertyId}/guests/{guestId}/signature` - - Multipart SVG file. - - Access: `ADMIN`/`MANAGER`. - - Stores data: writes file under documents root; updates `guest.signature_path`. -- `GET /properties/{propertyId}/guests/{guestId}/signature/file` - - Access: property member. - - Stores data: reads signature file path from `guest`. - -### Guest documents - -- `POST /properties/{propertyId}/guests/{guestId}/documents?bookingId=...` - - Multipart file. - - Access: `ADMIN`/`MANAGER`. - - Stores data: writes document file under docs root; inserts `guest_document`; queues AI extraction and updates `guest_document.extracted_data`. -- `GET /properties/{propertyId}/guests/{guestId}/documents` - - Access: `ADMIN`/`MANAGER`. - - Stores data: reads `guest_document`. -- `GET /properties/{propertyId}/guests/{guestId}/documents/stream` - - Access: `ADMIN`/`MANAGER`. - - Stores data: no writes; SSE extraction updates. -- `GET /properties/{propertyId}/guests/{guestId}/documents/{documentId}/file` - - Access: public with token OR `ADMIN`/`MANAGER`. - - Stores data: reads `guest_document` + filesystem. -- `DELETE /properties/{propertyId}/guests/{guestId}/documents/{documentId}` - - Access: `ADMIN`/`MANAGER`. - - Stores data: deletes file + `guest_document` row (only OPEN/CHECKED_IN booking). - -### Guest ratings - -- `POST /properties/{propertyId}/guests/{guestId}/ratings` - - Request: `GuestRatingCreateRequest`. - - Access: property member. - - Stores data: inserts `guest_rating`. -- `GET /properties/{propertyId}/guests/{guestId}/ratings` - - Access: property member. - - Stores data: reads `guest_rating`. - -## 12) Inbound Email APIs - -- `GET /properties/{propertyId}/inbound-emails/{emailId}/file` - - Access: `ADMIN`/`MANAGER`. - - Stores data: reads `inbound_email.raw_pdf_path` and PDF file. -- `POST /properties/{propertyId}/inbound-emails/manual` - - Multipart PDF. - - Access: `ADMIN`/`MANAGER`. - - Stores data: writes PDF under `/docs/emails`; inserts `inbound_email`; triggers ingestion workflow. - -## 13) Rate plan APIs - -- `POST /properties/{propertyId}/rate-plans` - - Request: `RatePlanCreateRequest`. - - Access: `ADMIN`/`MANAGER`. - - Stores data: inserts `rate_plan`. -- `GET /properties/{propertyId}/rate-plans?roomTypeCode=...` - - Access: property member. - - Stores data: reads `rate_plan`. -- `PUT /properties/{propertyId}/rate-plans/{ratePlanId}` - - Request: `RatePlanUpdateRequest`. - - Access: `ADMIN`/`MANAGER`. - - Stores data: updates `rate_plan`. -- `DELETE /properties/{propertyId}/rate-plans/{ratePlanId}` - - Access: `ADMIN`/`MANAGER`. - - Stores data: deletes `rate_calendar` rows for plan, then deletes `rate_plan`. -- `POST /properties/{propertyId}/rate-plans/{ratePlanId}/calendar` - - Request: `RateCalendarRangeUpsertRequest`. - - Access: `ADMIN`/`MANAGER`. - - Stores data: upserts `rate_calendar` rows in date range. -- `GET /properties/{propertyId}/rate-plans/{ratePlanId}/calendar?from=...&to=...` - - Access: property member. - - Stores data: reads `rate_calendar` + `rate_plan`; returns average. -- `DELETE /properties/{propertyId}/rate-plans/{ratePlanId}/calendar/{rateDate}` - - Access: `ADMIN`/`MANAGER`. - - Stores data: deletes one `rate_calendar` override row. - -## 14) Razorpay APIs - -### Settings + return + webhook - -- `GET /properties/{propertyId}/razorpay-settings` - - Access: `ADMIN`/`MANAGER`. - - Stores data: reads `razorpay_settings`. -- `PUT /properties/{propertyId}/razorpay-settings` - - Request: `RazorpaySettingsUpsertRequest`. - - Access: `ADMIN`. - - Stores data: inserts/updates `razorpay_settings`. -- `POST /properties/{propertyId}/razorpay/webhook` - - Access: public (signature validated). - - Stores data: inserts `razorpay_webhook_log`, inserts `razorpay_payment_attempt`, updates `razorpay_qr_request` / `razorpay_payment_link_request`, inserts `payment` for capture/refund events. -- `POST /properties/{propertyId}/razorpay/return/success` - - Access: public. - - Stores data: none. -- `POST /properties/{propertyId}/razorpay/return/failure` - - Access: public. - - Stores data: none. - -### QR + links + request close + refund - -- `POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr` - - Request: `RazorpayQrGenerateRequest`. - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: inserts `razorpay_qr_request` (or returns active existing). -- `GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/active` - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: reads `razorpay_qr_request`. -- `POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/close` - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: updates latest active `razorpay_qr_request.status`. -- `POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/{qrId}/close` - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: updates specific `razorpay_qr_request.status`. -- `GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/{qrId}/events` - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: reads `razorpay_webhook_log`. -- `GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/{qrId}/events/stream` - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: SSE stream only. -- `GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr` - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: reads `razorpay_qr_request`. - -- `POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/payment-link` - - Request: `RazorpayPaymentLinkCreateRequest`. - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: inserts `razorpay_payment_link_request` (or returns existing open one). -- `GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/requests` - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: reads open `razorpay_qr_request` + `razorpay_payment_link_request`. -- `POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/close` - - Request: `RazorpayPaymentRequestCloseRequest`. - - Access: `ADMIN`/`MANAGER`/`STAFF`. - - Stores data: updates closed status in corresponding Razorpay request row. -- `POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/refund` - - Request: `RazorpayRefundRequest`. - - Access: `ADMIN`/`MANAGER`/`FINANCE`. - - Stores data: no local insert here; refund call is external and webhook later records ledger entry. - ---- - -## Detailed example (as requested format) - -### Expected checkout planning API - -**Expected checkout API is:** - -`POST /properties/{propertyId}/bookings/{bookingId}/expected-dates` - -**What it does:** - -- Updates planned dates on booking (`expectedCheckinAt`, `expectedCheckoutAt`), not actual checkout. -- For `OPEN` bookings: can update both expected check-in and expected check-out. -- For `CHECKED_IN`: can update only `expectedCheckOutAt` (check-in change is blocked). -- For `CHECKED_OUT` / `CANCELLED` / `NO_SHOW`: returns conflict (`Booking closed`). -- Validates range: if both are present, checkout must be after checkin. -- Returns `204 No Content`. -- Emits booking SSE update event. - -**Request body (`BookingExpectedDatesUpdateRequest`):** - -```json -{ - "expectedCheckInAt": "2026-02-05T12:00:00+05:30", - "expectedCheckOutAt": "2026-02-06T11:00:00+05:30" -} -``` - -**Allowed roles:** - -- `ADMIN`, `MANAGER`, `STAFF` (property-scoped) -- `superAdmin` can also access (bypasses property membership/role checks) -- Requires authenticated Firebase principal (`MyPrincipal`) - -**Data store:** - -- Updates row in `booking` table (`expected_checkin_at`, `expected_checkout_at`, `updated_at`) - -**Error codes:** - -- `400 Bad Request` - - Invalid timestamp format (`"Invalid timestamp"`) for `expectedCheckInAt` / `expectedCheckOutAt` - - Invalid range (`"Invalid date range"`) when checkout is not after check-in -- `401 Unauthorized` - - Missing auth principal / user not found -- `403 Forbidden` - - Authenticated but not a property member or missing role (`ADMIN`, `MANAGER`, `STAFF`) -- `404 Not Found` - - Booking not found, or booking does not belong to that property -- `409 Conflict` - - `"Cannot change expected check-in after check-in"` - - `"Booking closed"` for `CHECKED_OUT`, `CANCELLED`, `NO_SHOW` - diff --git a/docs/API_REFERENCE.txt b/docs/API_REFERENCE.txt new file mode 100644 index 0000000..b513d92 --- /dev/null +++ b/docs/API_REFERENCE.txt @@ -0,0 +1,3023 @@ +Trisolaris Server API Documentation (TXT Manual) +Generated manually from current controller code. +Date: 2026-02-04 + +Global behavior + +- Base domain: api.hoteltrisolaris.in +- Auth model: Firebase principal (MyPrincipal) +- superAdmin behavior: bypasses property membership and role checks in PropertyAccess +- Standard error payload: + { + "timestamp": "...", + "status": 400, + "error": "Bad Request", + "message": "...", + "path": "/..." + } + +================================================================================ +AUTH + SYSTEM APIS +================================================================================ + +- Health API is this one: + + GET /health + + What it does: + + - Returns server health payload. + - Returns build string and status. + + Request body: + + - None. + + - Allowed roles: Public endpoint. + - No Firebase principal required. + + Error Codes + + - 500 Internal Server Error (unexpected failure) + + +- Root health API is this one: + + GET / + + What it does: + + - Same payload as /health. + + Request body: + + - None. + + - Allowed roles: Public endpoint. + + Error Codes + + - 500 Internal Server Error (unexpected failure) + + +- Verify auth API is this one: + + POST /auth/verify + + What it does: + + - Resolves Firebase user from request token. + - Returns user profile and property memberships. + + Request body: + + - None. + + - Allowed roles: Public route, but valid Firebase token expected for successful verify. + - Requires authenticated Firebase principal flow. + + Error Codes + + - 401 Unauthorized (token missing/invalid) + + +- Me auth API is this one: + + GET /auth/me + + What it does: + + - Returns current app user details and memberships. + + Request body: + + - None. + + - Allowed roles: Public route, valid Firebase token required for authenticated response. + + Error Codes + + - 401 Unauthorized (token missing/invalid) + + +- Update profile API is this one: + + PUT /auth/me + + What it does: + + - Updates current user name in app_user. + + Request body (UpdateMeRequest): + + { + "name": "Your Name" + } + + - Allowed roles: authenticated Firebase user. + - superAdmin and normal users both allowed. + + Error Codes + + - 401 Unauthorized (missing principal / user not found) + +================================================================================ +PROPERTY + USER APIS +================================================================================ + +- Create property API is this one: + + POST /properties + + What it does: + + - Creates property with generated 7-char code. + - Auto-assigns creator as ADMIN in property_user. + + Request body (PropertyCreateRequest): + + { + "name": "Hotel Trisolaris", + "addressText": "Varanasi", + "timezone": "Asia/Kolkata", + "currency": "INR", + "billingCheckinTime": "12:00", + "billingCheckoutTime": "11:00", + "active": true, + "otaAliases": ["MMT"], + "emailAddresses": ["booking@hotel.com"], + "allowedTransportModes": ["CAR", "BIKE"] + } + + - Allowed roles: any authenticated app user. + + Error Codes + + - 401 Unauthorized (missing principal / user not found) + - 409 Conflict (unable to generate unique property code) + + +- List properties API is this one: + + GET /properties + + What it does: + + - superAdmin: returns all properties. + - non-superAdmin: returns only joined properties. + + Request body: + + - None. + + - Allowed roles: authenticated user. + + Error Codes + + - 401 Unauthorized (missing principal / user not found) + + +- Property code API is this one: + + GET /properties/{propertyId}/code + + What it does: + + - Returns property join code. + + Request body: + + - None. + + - Allowed roles: property member. + - superAdmin can also access. + + Error Codes + + - 401 Unauthorized (missing principal) + - 403 Forbidden (not member) + - 404 Not Found (property not found) + + +- Get property billing policy API is this one: + + GET /properties/{propertyId}/billing-policy + + What it does: + + - Returns billing check-in and check-out time for property. + + Request body: + + - None. + + - Allowed roles: property member. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Update property billing policy API is this one: + + PUT /properties/{propertyId}/billing-policy + + What it does: + + - Updates default billing policy at property level. + + Request body (PropertyBillingPolicyRequest): + + { + "billingCheckinTime": "12:00", + "billingCheckoutTime": "11:00" + } + + - Allowed roles: ADMIN (property-scoped) + - superAdmin can also access. + + Error Codes + + - 400 Bad Request (time format invalid, must be HH:mm) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- List property users API is this one: + + GET /properties/{propertyId}/users + + What it does: + + - Returns property users below/at actor hierarchy visibility. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER + - superAdmin can also access. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + + +- Update property user roles API is this one: + + PUT /properties/{propertyId}/users/{userId}/roles + + What it does: + + - Creates/updates property membership roles. + - Enforces role-assignment hierarchy. + + Request body (PropertyUserRoleRequest): + + { + "roles": ["STAFF"] + } + + - Allowed roles: + - superAdmin + - ADMIN (ADMIN/MANAGER/STAFF/AGENT) + - MANAGER (STAFF/AGENT only) + + Error Codes + + - 400 Bad Request (unknown role) + - 401 Unauthorized + - 403 Forbidden (missing role / role not allowed) + - 404 Not Found (property/user) + + +- Disable property user API is this one: + + PUT /properties/{propertyId}/users/{userId}/disabled + + What it does: + + - Enables/disables a property membership. + - Enforces hierarchy restrictions. + + Request body (PropertyUserDisableRequest): + + { + "disabled": true + } + + - Allowed roles: superAdmin, ADMIN, MANAGER (hierarchy limited) + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Delete property user API is this one: + + DELETE /properties/{propertyId}/users/{userId} + + What it does: + + - Removes user membership from property. + + Request body: + + - None. + + - Allowed roles: ADMIN + - superAdmin can also access. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + + +- Update property API is this one: + + PUT /properties/{propertyId} + + What it does: + + - Updates property master data. + + Request body (PropertyUpdateRequest): + + { + "code": "ABC1234", + "name": "Hotel Trisolaris", + "addressText": "Varanasi" + } + + - Allowed roles: ADMIN + - superAdmin can also access. + + Error Codes + + - 400 Bad Request (transport mode unknown / time invalid) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 409 Conflict (property code exists) + + +- Create access code API is this one: + + POST /properties/{propertyId}/access-codes + + What it does: + + - Creates 6-digit one-time join code with 1-minute expiry. + + Request body (PropertyAccessCodeCreateRequest): + + { + "roles": ["STAFF"] + } + + - Allowed roles: ADMIN + - superAdmin can also access. + + Error Codes + + - 400 Bad Request (ADMIN role in invite / roles empty / unknown role) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (property) + - 409 Conflict (cannot generate code) + + +- Join with access code API is this one: + + POST /properties/access-codes/join + + What it does: + + - Joins current user to property using propertyCode + PIN. + - Marks code as used. + + Request body (PropertyAccessCodeJoinRequest): + + { + "propertyCode": "ABC1234", + "code": "123456" + } + + - Allowed roles: authenticated user. + + Error Codes + + - 400 Bad Request (property code required) + - 401 Unauthorized + - 404 Not Found (invalid code / property not found) + - 409 Conflict (already a member) + + +- Global users list API is this one: + + GET /users + + What it does: + + - Lists app users for super admin (optional phone filter). + + Request body: + + - None. + + - Allowed roles: superAdmin only. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden (super admin only) + + +- Property user search API is this one: + + GET /properties/{propertyId}/users/search + + What it does: + + - Searches property members by phone. + - Applies hierarchy visibility filter. + + Request body: + + - None. + + - Allowed roles: ADMIN + - superAdmin can also access. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + + +- Get cancellation policy API is this one: + + GET /properties/{propertyId}/cancellation-policy + + What it does: + + - Returns property cancellation policy. + - If not set, returns default values. + + Request body: + + - None. + + - Allowed roles: Public endpoint. + + Error Codes + + - 500 Internal Server Error (unexpected) + + +- Upsert cancellation policy API is this one: + + PUT /properties/{propertyId}/cancellation-policy + + What it does: + + - Creates/updates cancellation policy. + + Request body (CancellationPolicyUpsertRequest): + + { + "freeDaysBeforeCheckin": 2, + "penaltyMode": "ONE_NIGHT" + } + + - Allowed roles: ADMIN + - superAdmin can also access. + + Error Codes + + - 400 Bad Request (freeDaysBeforeCheckin < 0 / unknown penaltyMode) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (property) + + +- Transport modes API is this one: + + GET /properties/{propertyId}/transport-modes + + What it does: + + - Returns enabled transport modes for property. + + Request body: + + - None. + + - Allowed roles: property member. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (property) + +================================================================================ +ROOM AMENITIES + TAGS + ICONS +================================================================================ + +- List amenities API is this one: + + GET /amenities + + What it does: + + - Returns all room amenities. + + Request body: + + - None. + + - Allowed roles: authenticated user. + + Error Codes + + - 401 Unauthorized + + +- Create amenity API is this one: + + POST /amenities + + What it does: + + - Creates amenity master row. + + Request body (AmenityUpsertRequest): + + { + "name": "WiFi", + "category": "comfort", + "iconKey": "wifi" + } + + - Allowed roles: superAdmin only. + + Error Codes + + - 400 Bad Request (icon key missing on disk) + - 401 Unauthorized + - 403 Forbidden + - 409 Conflict (amenity already exists) + + +- Update amenity API is this one: + + PUT /amenities/{amenityId} + + What it does: + + - Updates amenity name/category/icon. + + Request body (AmenityUpsertRequest): + + { + "name": "WiFi", + "category": "comfort", + "iconKey": "wifi" + } + + - Allowed roles: superAdmin only. + + Error Codes + + - 400 Bad Request + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 409 Conflict + + +- Delete amenity API is this one: + + DELETE /amenities/{amenityId} + + What it does: + + - Deletes amenity and detaches it from room types. + + Request body: + + - None. + + - Allowed roles: superAdmin only. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- List image tags API is this one: + + GET /image-tags + + What it does: + + - Returns room image tags. + + Request body: + + - None. + + - Allowed roles: Public endpoint. + + Error Codes + + - 500 Internal Server Error (unexpected) + + +- Create image tag API is this one: + + POST /image-tags + + What it does: + + - Creates image tag. + + Request body (RoomImageTagUpsertRequest): + + { + "name": "Lobby" + } + + - Allowed roles: superAdmin only. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 409 Conflict + + +- Update image tag API is this one: + + PUT /image-tags/{tagId} + + What it does: + + - Updates image tag name. + + Request body (RoomImageTagUpsertRequest): + + { + "name": "Lobby" + } + + - Allowed roles: superAdmin only. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 409 Conflict + + +- Delete image tag API is this one: + + DELETE /image-tags/{tagId} + + What it does: + + - Deletes tag and removes links from room images. + + Request body: + + - None. + + - Allowed roles: superAdmin only. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Icon list API is this one: + + GET /icons/png + + What it does: + + - Lists PNG files in icon folder. + + Request body: + + - None. + + - Allowed roles: Public endpoint. + + Error Codes + + - 500 Internal Server Error (unexpected) + + +- Icon file API is this one: + + GET /icons/png/{filename} + + What it does: + + - Streams requested icon PNG file. + + Request body: + + - None. + + - Allowed roles: Public endpoint. + + Error Codes + + - 400 Bad Request (path traversal attempt) + - 404 Not Found + +================================================================================ +ROOM TYPE + ROOMS + ROOM IMAGES +================================================================================ + +- List room types API is this one: + + GET /properties/{propertyId}/room-types + + What it does: + + - Returns room types with amenity + alias data. + + Request body: + + - None. + + - Allowed roles: Public endpoint. If principal present, member check is applied. + + Error Codes + + - 403 Forbidden (when principal provided but user not member) + + +- Resolve room type rate API is this one: + + GET /properties/{propertyId}/room-types/{roomTypeCode}/rate + + What it does: + + - Resolves effective rate for date with optional rate plan. + + Request body: + + - None. + + Query params: + + - date (required, YYYY-MM-DD) + - ratePlanCode (optional) + + - Allowed roles: Public endpoint. If principal present, member check is applied. + + Error Codes + + - 400 Bad Request (invalid date / plan-roomType mismatch) + - 404 Not Found (property/room type/rate plan/default rate) + + +- Create room type API is this one: + + POST /properties/{propertyId}/room-types + + What it does: + + - Creates room type for property. + + Request body (RoomTypeUpsertRequest): + + { + "code": "DLX", + "name": "Deluxe", + "baseOccupancy": 2, + "maxOccupancy": 3, + "defaultRate": 4500 + } + + - Allowed roles: ADMIN, MANAGER + - superAdmin can also access. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (property/amenity) + - 409 Conflict (room type code exists) + + +- Update room type API is this one: + + PUT /properties/{propertyId}/room-types/{roomTypeId} + + What it does: + + - Updates room type metadata. + + Request body (RoomTypeUpsertRequest): + + { + "code": "DLX", + "name": "Deluxe" + } + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 409 Conflict + + +- Delete room type API is this one: + + DELETE /properties/{propertyId}/room-types/{roomTypeId} + + What it does: + + - Soft deletes room type by setting active=false. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- List rooms API is this one: + + GET /properties/{propertyId}/rooms + + What it does: + + - Returns rooms for property. + - AGENT-only users see only free sellable rooms. + + Request body: + + - None. + + - Allowed roles: property member. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + + +- Room board API is this one: + + GET /properties/{propertyId}/rooms/board + + What it does: + + - Returns room board statuses (FREE/OCCUPIED/MAINTENANCE/INACTIVE). + + Request body: + + - None. + + - Allowed roles: property member. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + + +- Room board stream API is this one: + + GET /properties/{propertyId}/rooms/board/stream + + What it does: + + - SSE stream for room board updates. + + Request body: + + - None. + + - Allowed roles: property member. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + + +- Room availability API is this one: + + GET /properties/{propertyId}/rooms/availability + + What it does: + + - Returns free room numbers grouped by room type. + + Request body: + + - None. + + - Allowed roles: property member. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + + +- Public available rooms API is this one: + + GET /properties/{propertyId}/rooms/available + + What it does: + + - Returns currently available rooms. + + Request body: + + - None. + + - Allowed roles: Public endpoint. + + Error Codes + + - 500 Internal Server Error (unexpected) + + +- Rooms by type API is this one: + + GET /properties/{propertyId}/rooms/by-type/{roomTypeCode} + + What it does: + + - Returns rooms for room type. + - Supports availableOnly filter. + + Request body: + + - None. + + Query params: + + - availableOnly=true|false (optional) + + - Allowed roles: Public endpoint. + + Error Codes + + - 404 Not Found (room type) + + +- Availability range API is this one: + + GET /properties/{propertyId}/rooms/availability-range + + What it does: + + - Returns free rooms in date range. + + Request body: + + - None. + + Query params: + + - from=YYYY-MM-DD + - to=YYYY-MM-DD + + - Allowed roles: property member. + + Error Codes + + - 400 Bad Request (invalid date/range) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (property) + + +- Availability with rate API is this one: + + GET /properties/{propertyId}/rooms/available-range-with-rate + + What it does: + + - Returns available rooms with average rate over date range. + + Request body: + + - None. + + Query params: + + - from=YYYY-MM-DD + - to=YYYY-MM-DD + - ratePlanCode (optional) + + - Allowed roles: property member. + + Error Codes + + - 400 Bad Request (invalid date/range) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (property) + + +- Create room API is this one: + + POST /properties/{propertyId}/rooms + + What it does: + + - Creates room inventory entry. + + Request body (RoomUpsertRequest): + + { + "roomNumber": 101, + "floor": 1, + "roomTypeCode": "DLX", + "hasNfc": true, + "active": true, + "maintenance": false + } + + - Allowed roles: ADMIN + - superAdmin can also access. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (property / room type) + - 409 Conflict (room number already exists) + + +- Update room API is this one: + + PUT /properties/{propertyId}/rooms/{roomId} + + What it does: + + - Updates room metadata. + + Request body (RoomUpsertRequest): + + { + "roomNumber": 101, + "roomTypeCode": "DLX", + "hasNfc": true, + "active": true, + "maintenance": false + } + + - Allowed roles: ADMIN + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 409 Conflict + + +- Delete room API is this one: + + DELETE /properties/{propertyId}/rooms/{roomId} + + What it does: + + - Deletes room if no stays exist. + - Deletes room image files + DB rows first. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 409 Conflict (room has stays) + - 500 Internal Server Error (file delete failure) + + +- Room image list API is this one: + + GET /properties/{propertyId}/rooms/{roomId}/images + + What it does: + + - Lists room images. + - Auto-cleans rows whose files are missing. + + Request body: + + - None. + + - Allowed roles: Public endpoint. + + Error Codes + + - 404 Not Found (room) + + +- Room image upload API is this one: + + POST /properties/{propertyId}/rooms/{roomId}/images + + What it does: + + - Uploads room image and thumbnail. + - Stores hash and optional tags. + + Request body: + + - multipart/form-data + - file (required) + - tagIds (optional list) + + - Allowed roles: ADMIN, MANAGER + - superAdmin can also access. + + Error Codes + + - 400 Bad Request (empty/invalid image) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (room/tag) + - 409 Conflict (duplicate image hash) + + +- Room image delete API is this one: + + DELETE /properties/{propertyId}/rooms/{roomId}/images/{imageId} + + What it does: + + - Deletes image files and DB row. + - Reorders room and roomType image sort orders. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 500 Internal Server Error (file delete failure) + + +- Room image tags update API is this one: + + PUT /properties/{propertyId}/rooms/{roomId}/images/{imageId}/tags + + What it does: + + - Replaces tag set for image. + + Request body (RoomImageTagUpdateRequest): + + { + "tagIds": ["uuid-1", "uuid-2"] + } + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Room image reorder (room) API is this one: + + PUT /properties/{propertyId}/rooms/{roomId}/images/reorder-room + + What it does: + + - Sets explicit order among images for one room. + + Request body (RoomImageReorderRequest): + + { + "imageIds": ["uuid-1", "uuid-2"] + } + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 400 Bad Request (images not in room) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Room image reorder (room type) API is this one: + + PUT /properties/{propertyId}/rooms/{roomId}/images/reorder-room-type + + What it does: + + - Sets explicit order for room-type gallery sequence. + + Request body (RoomImageReorderRequest): + + { + "imageIds": ["uuid-1", "uuid-2"] + } + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 400 Bad Request (image-property/roomType mismatch) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Room image file API is this one: + + GET /properties/{propertyId}/rooms/{roomId}/images/{imageId}/file + + What it does: + + - Streams full-size or thumbnail room image. + + Request body: + + - None. + + Query params: + + - size=full|thumb (optional, default full) + + - Allowed roles: Public endpoint. + + Error Codes + + - 404 Not Found (image/file) + + +- Room type images API is this one: + + GET /properties/{propertyId}/room-types/{roomTypeCode}/images + + What it does: + + - Lists all room images for a room type. + - Auto-cleans rows with missing files. + + Request body: + + - None. + + - Allowed roles: Public endpoint. + + Error Codes + + - 404 Not Found (room type) + +================================================================================ +ROOM STAYS + CARDS APIS +================================================================================ + +- Active room stays API is this one: + + GET /properties/{propertyId}/room-stays/active + + What it does: + + - Returns active stays with booking and guest details. + - AGENT-only users are blocked. + + Request body: + + - None. + + - Allowed roles: property member except AGENT-only. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + + +- Void room stay API is this one: + + POST /properties/{propertyId}/room-stays/{roomStayId}/void + + What it does: + + - Soft-voids active room stay. + - Writes room stay audit log. + + Request body (RoomStayVoidRequest): + + { + "reason": "Duplicate entry" + } + + - Allowed roles: ADMIN, MANAGER, STAFF + - STAFF blocked after first booking payment. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (room stay) + - 409 Conflict (already checked-out) + + +- Prepare issued card API is this one: + + POST /properties/{propertyId}/room-stays/{roomStayId}/cards/prepare + + What it does: + + - Allocates cardIndex. + - Returns NFC sector payload for encoding. + + Request body (CardPrepareRequest): + + { + "expiresAt": "2026-02-06T11:00:00+05:30" + } + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 400 Bad Request (expiresAt invalid or not after issuedAt) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (room stay/property) + - 409 Conflict (room stay closed) + + +- Issue card API is this one: + + POST /properties/{propertyId}/room-stays/{roomStayId}/cards + + What it does: + + - Persists issued stay card. + + Request body (IssueCardRequest): + + { + "cardId": "CARD123", + "cardIndex": 10001, + "issuedAt": "2026-02-05T12:00:00+05:30", + "expiresAt": "2026-02-06T11:00:00+05:30" + } + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 400 Bad Request (missing cardId/cardIndex/invalid times) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 409 Conflict (active card exists) + + +- List issued cards API is this one: + + GET /properties/{propertyId}/room-stays/{roomStayId}/cards + + What it does: + + - Lists all issued cards for stay. + + Request body: + + - None. + + - Allowed roles: STAFF, ADMIN, MANAGER, SUPERVISOR + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Revoke card API is this one: + + POST /properties/{propertyId}/room-stays/cards/{cardIndex}/revoke + + What it does: + + - Revokes card by cardIndex. + - Returns revoke payload timeData. + + Request body: + + - None. + + - Allowed roles: + - regular card: ADMIN + - temp card: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (card) + + +- Get card by index API is this one: + + GET /properties/{propertyId}/room-stays/cards/{cardIndex} + + What it does: + + - Returns card details. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Prepare temp card API is this one: + + POST /properties/{propertyId}/rooms/{roomId}/cards/prepare-temp + + What it does: + + - Allocates temporary card payload (7-minute validity). + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (room/property) + + +- Issue temp card API is this one: + + POST /properties/{propertyId}/rooms/{roomId}/cards/temp + + What it does: + + - Stores temporary room-only card record. + + Request body (IssueTempCardRequest): + + { + "cardId": "CARD123", + "cardIndex": 10002, + "issuedAt": "2026-02-05T12:00:00+05:30" + } + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 400 Bad Request (cardId/cardIndex invalid) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (room) + - 409 Conflict (active card exists) + +================================================================================ +BOOKING APIS +================================================================================ + +- Create booking API is this one: + + POST /properties/{propertyId}/bookings + + What it does: + + - Creates booking in OPEN state. + - Creates/links placeholder guest by phone. + + Request body (BookingCreateRequest): + + { + "source": "WALKIN", + "expectedCheckInAt": "2026-02-05T12:00:00+05:30", + "expectedCheckOutAt": "2026-02-06T11:00:00+05:30" + } + + - Allowed roles: ADMIN, MANAGER, STAFF + - superAdmin can also access. + + Error Codes + + - 400 Bad Request (required fields/date range/unknown enums) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (property) + + +- List bookings API is this one: + + GET /properties/{propertyId}/bookings + + What it does: + + - Lists bookings with summary and computed pending amount. + + Request body: + + - None. + + Query params: + + - status (optional comma-separated) + + - Allowed roles: ADMIN, MANAGER, STAFF, HOUSEKEEPING, FINANCE + + Error Codes + + - 400 Bad Request (invalid status) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (property) + + +- Get booking detail API is this one: + + GET /properties/{propertyId}/bookings/{bookingId} + + What it does: + + - Returns booking snapshot details with stays, billing, ledger. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER, STAFF, HOUSEKEEPING, FINANCE + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Booking stream API is this one: + + GET /properties/{propertyId}/bookings/{bookingId}/stream + + What it does: + + - SSE stream of booking updates. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER, STAFF, HOUSEKEEPING, FINANCE + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Link guest API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/link-guest + + What it does: + + - Links booking to existing guest in same property. + + Request body (BookingLinkGuestRequest): + + { + "guestId": "uuid" + } + + - Allowed roles: property member. + + Error Codes + + - 400 Bad Request (guest not in property) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (booking/guest) + + +- Bulk check-in API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/check-in/bulk + + What it does: + + - Creates room stays in one request. + - Marks booking as CHECKED_IN. + + Request body (BookingBulkCheckInRequest): + + { + "stays": [ + { + "roomId": "uuid", + "checkInAt": "2026-02-05T12:00:00+05:30", + "nightlyRate": 4500, + "rateSource": "MANUAL" + } + ] + } + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 400 Bad Request (stays missing/duplicate roomId/unknown enum) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (booking/room) + - 409 Conflict (booking not open/room unavailable) + + +- Expected checkout API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/expected-dates + + What it does: + + - Updates planned dates on booking (expectedCheckInAt, expectedCheckOutAt), not actual checkout. + - For OPEN bookings: can update both expected check-in and expected check-out. + - For CHECKED_IN: can update only expectedCheckOutAt (check-in change is blocked). + - For CHECKED_OUT / CANCELLED / NO_SHOW: returns conflict (Booking closed). + - Validates range: if both are present, checkout must be after checkin. + - Returns 204 No Content. + + Request body (BookingExpectedDatesUpdateRequest): + + { + "expectedCheckInAt": "2026-02-05T12:00:00+05:30", + "expectedCheckOutAt": "2026-02-06T11:00:00+05:30" + } + + - Allowed roles: ADMIN, MANAGER, STAFF (property-scoped) + - superAdmin can also access (bypasses property membership/role checks) + - Requires authenticated Firebase principal (MyPrincipal) + + Error Codes + + - 400 Bad Request + - Invalid timestamp format ("Invalid timestamp") for expectedCheckInAt / expectedCheckOutAt + - Invalid range ("Invalid date range") when checkout is not after check-in + - 401 Unauthorized + - Missing auth principal / user not found + - 403 Forbidden + - Authenticated but not a property member or missing role (ADMIN, MANAGER, STAFF) + - 404 Not Found + - Booking not found, or booking does not belong to that property + - 409 Conflict + - "Cannot change expected check-in after check-in" + - "Booking closed" for CHECKED_OUT, CANCELLED, NO_SHOW + + +- Update booking billing policy API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/billing-policy + + What it does: + + - Updates booking billing mode/window. + - Writes billing policy audit log when changed. + + Request body (BookingBillingPolicyUpdateRequest): + + { + "billingMode": "PROPERTY_POLICY", + "billingCheckoutTime": "11:00" + } + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 400 Bad Request (unknown billing mode/time invalid) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 409 Conflict (booking closed) + + +- Booking check-out API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/check-out + + What it does: + + - Checks out all active room stays for booking. + - Updates booking to CHECKED_OUT. + + Request body (BookingCheckOutRequest): + + { + "checkOutAt": "2026-02-06T11:00:00+05:30", + "notes": "Early checkout" + } + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 400 Bad Request (invalid timestamp) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 409 Conflict + - Booking not checked in + - Room stay amount outside allowed range + - Ledger mismatch tolerance failure + + +- Room-stay specific check-out API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/room-stays/{roomStayId}/check-out + + What it does: + + - Checks out a specific room stay. + - Auto-closes booking when last active stay closes. + + Request body (BookingCheckOutRequest): + + { + "checkOutAt": "2026-02-06T11:00:00+05:30", + "notes": "Shifted room" + } + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 400 Bad Request (invalid timestamp) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (booking/stay) + - 409 Conflict (booking not checked in / amount or minimum duration invalid) + + +- Cancel booking API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/cancel + + What it does: + + - Marks booking CANCELLED. + - May create CANCELLATION_PENALTY charge. + + Request body (BookingCancelRequest): + + { + "reason": "Guest cancelled" + } + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 409 Conflict (cannot cancel checked-in booking with active stays) + + +- No-show booking API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/no-show + + What it does: + + - Marks booking NO_SHOW. + - May create NO_SHOW_PENALTY charge. + + Request body (BookingNoShowRequest): + + { + "reason": "Guest not arrived" + } + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 409 Conflict (booking not open) + + +- Create room request API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/room-requests + + What it does: + + - Creates quantity-based room-type reservation hold. + + Request body (BookingRoomRequestCreateRequest): + + { + "roomTypeCode": "DLX", + "quantity": 2, + "fromAt": "2026-02-05T12:00:00+05:30", + "toAt": "2026-02-06T11:00:00+05:30" + } + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 400 Bad Request (quantity/date invalid) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (booking/room type) + - 409 Conflict (booking closed / insufficient availability) + + +- List room requests API is this one: + + GET /properties/{propertyId}/bookings/{bookingId}/room-requests + + What it does: + + - Lists room-type quantity requests for booking. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER, STAFF, HOUSEKEEPING, FINANCE + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Cancel room request API is this one: + + DELETE /properties/{propertyId}/bookings/{bookingId}/room-requests/{requestId} + + What it does: + + - Cancels room request if not fulfilled. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 409 Conflict (request already fulfilled) + + +- Booking balance API is this one: + + GET /properties/{propertyId}/bookings/{bookingId}/balance + + What it does: + + - Returns expectedPay, amountCollected, pending. + + Request body: + + - None. + + - Allowed roles: property member. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + +================================================================================ +CHARGES + PAYMENTS APIS +================================================================================ + +- Create charge API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/charges + + What it does: + + - Adds ledger charge row. + + Request body (ChargeCreateRequest): + + { + "type": "EXTRA_SERVICE", + "amount": 500, + "currency": "INR", + "occurredAt": "2026-02-05T15:00:00+05:30", + "notes": "Laundry" + } + + - Allowed roles: ADMIN, MANAGER, FINANCE + + Error Codes + + - 400 Bad Request (amount <= 0 / unknown type / invalid timestamp) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- List charges API is this one: + + GET /properties/{propertyId}/bookings/{bookingId}/charges + + What it does: + + - Returns booking charge ledger rows. + + Request body: + + - None. + + - Allowed roles: property member. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Create payment API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/payments + + What it does: + + - Adds payment ledger row. + + Request body (PaymentCreateRequest): + + { + "amount": 1000, + "method": "CASH", + "currency": "INR", + "receivedAt": "2026-02-05T16:00:00+05:30", + "notes": "Advance" + } + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 400 Bad Request (amount <= 0 / unknown method / invalid timestamp) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- List payments API is this one: + + GET /properties/{propertyId}/bookings/{bookingId}/payments + + What it does: + + - Returns booking payment ledger rows. + + Request body: + + - None. + + - Allowed roles: property member. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Delete payment API is this one: + + DELETE /properties/{propertyId}/bookings/{bookingId}/payments/{paymentId} + + What it does: + + - Deletes payment row under strict rules. + + Request body: + + - None. + + - Allowed roles: ADMIN + - superAdmin can also access. + + Error Codes + + - 400 Bad Request + - Only CASH payments can be deleted + - Booking must be OPEN or CHECKED_IN + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + +================================================================================ +GUEST + DOCUMENT + RATING APIS +================================================================================ + +- Update guest API is this one: + + PUT /properties/{propertyId}/guests/{guestId} + + What it does: + + - Updates guest profile fields. + + Request body (GuestUpdateRequest): + + { + "phoneE164": "+919999999999", + "name": "John", + "nationality": "Indian", + "addressText": "Varanasi" + } + + - Allowed roles: property member. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 409 Conflict (phone already exists) + + +- Guest search API is this one: + + GET /properties/{propertyId}/guests/search + + What it does: + + - Searches guest by phone or vehicle number. + + Request body: + + - None. + + Query params: + + - phone (optional) + - vehicleNumber (optional) + + - Allowed roles: property member. + + Error Codes + + - 400 Bad Request (phone or vehicleNumber required) + - 401 Unauthorized + - 403 Forbidden + + +- Get guest API is this one: + + GET /properties/{propertyId}/guests/{guestId} + + What it does: + + - Returns guest profile with vehicles + average score. + + Request body: + + - None. + + - Allowed roles: property member. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Guest visit count API is this one: + + GET /properties/{propertyId}/guests/visit-count + + What it does: + + - Returns booking count by phone number. + + Request body: + + - None. + + Query params: + + - phone (required) + + - Allowed roles: property member. + + Error Codes + + - 400 Bad Request (phone required) + - 401 Unauthorized + - 403 Forbidden + + +- Add guest vehicle API is this one: + + POST /properties/{propertyId}/guests/{guestId}/vehicles + + What it does: + + - Adds or updates vehicle mapping to booking + guest. + + Request body (GuestVehicleRequest): + + { + "vehicleNumber": "UP65AB1234", + "bookingId": "uuid" + } + + - Allowed roles: property member. + + Error Codes + + - 400 Bad Request (booking not in property) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (guest/booking) + - 409 Conflict (vehicle linked to different guest) + + +- Upload guest signature API is this one: + + POST /properties/{propertyId}/guests/{guestId}/signature + + What it does: + + - Uploads guest signature SVG and stores file path. + + Request body: + + - multipart/form-data file (SVG) + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 400 Bad Request (file empty / only SVG allowed) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Download guest signature API is this one: + + GET /properties/{propertyId}/guests/{guestId}/signature/file + + What it does: + + - Returns guest signature SVG file. + + Request body: + + - None. + + - Allowed roles: property member. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Upload guest document API is this one: + + POST /properties/{propertyId}/guests/{guestId}/documents + + What it does: + + - Uploads guest document file for booking. + - Queues AI extraction. + + Request body: + + - multipart/form-data + - query param bookingId (required) + - file (required) + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 400 Bad Request (file empty / video not allowed / booking-guest mismatch) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (property/guest/booking) + - 409 Conflict (duplicate document hash) + + +- List guest documents API is this one: + + GET /properties/{propertyId}/guests/{guestId}/documents + + What it does: + + - Lists guest documents with extracted data. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + + +- Guest document stream API is this one: + + GET /properties/{propertyId}/guests/{guestId}/documents/stream + + What it does: + + - SSE stream for document updates/extraction completion. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + + +- Download guest document API is this one: + + GET /properties/{propertyId}/guests/{guestId}/documents/{documentId}/file + + What it does: + + - Downloads stored document. + - Supports token-based access. + + Request body: + + - None. + + Query params: + + - token (optional) + + - Allowed roles: ADMIN, MANAGER OR valid token. + + Error Codes + + - 401 Unauthorized (invalid token / missing auth) + - 403 Forbidden + - 404 Not Found (document/file) + + +- Delete guest document API is this one: + + DELETE /properties/{propertyId}/guests/{guestId}/documents/{documentId} + + What it does: + + - Deletes document row + file. + - Allowed only when booking is OPEN or CHECKED_IN. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 400 Bad Request (booking status not OPEN/CHECKED_IN) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 500 Internal Server Error (file delete failure) + + +- Create guest rating API is this one: + + POST /properties/{propertyId}/guests/{guestId}/ratings + + What it does: + + - Creates guest rating for booking. + + Request body (GuestRatingCreateRequest): + + { + "bookingId": "uuid", + "score": "GOOD", + "notes": "Polite guest" + } + + - Allowed roles: property member. + + Error Codes + + - 400 Bad Request (score invalid / booking mismatch) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + - 409 Conflict (rating already exists) + + +- List guest ratings API is this one: + + GET /properties/{propertyId}/guests/{guestId}/ratings + + What it does: + + - Returns rating history for guest. + + Request body: + + - None. + + - Allowed roles: property member. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + +================================================================================ +INBOUND EMAIL APIS +================================================================================ + +- Inbound email PDF API is this one: + + GET /properties/{propertyId}/inbound-emails/{emailId}/file + + What it does: + + - Downloads stored inbound email PDF audit file. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (email/pdf) + + +- Manual inbound email upload API is this one: + + POST /properties/{propertyId}/inbound-emails/manual + + What it does: + + - Uploads PDF manually for email ingestion workflow. + + Request body: + + - multipart/form-data file (PDF) + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 400 Bad Request (file empty / non-PDF) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (property) + +================================================================================ +RATE PLAN APIS +================================================================================ + +- Create rate plan API is this one: + + POST /properties/{propertyId}/rate-plans + + What it does: + + - Creates rate plan for room type. + + Request body (RatePlanCreateRequest): + + { + "code": "CP", + "name": "Corporate", + "roomTypeCode": "DLX", + "baseRate": 4500, + "currency": "INR" + } + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (property/room type) + - 409 Conflict (duplicate code) + + +- List rate plans API is this one: + + GET /properties/{propertyId}/rate-plans + + What it does: + + - Lists rate plans for property. + - Optional roomTypeCode filter. + + Request body: + + - None. + + - Allowed roles: property member. + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + + +- Update rate plan API is this one: + + PUT /properties/{propertyId}/rate-plans/{ratePlanId} + + What it does: + + - Updates plan name/baseRate/currency. + + Request body (RatePlanUpdateRequest): + + { + "name": "Corporate", + "baseRate": 5000, + "currency": "INR" + } + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Delete rate plan API is this one: + + DELETE /properties/{propertyId}/rate-plans/{ratePlanId} + + What it does: + + - Deletes rate plan and related calendar overrides. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Upsert rate calendar API is this one: + + POST /properties/{propertyId}/rate-plans/{ratePlanId}/calendar + + What it does: + + - Upserts per-day rate overrides for date range. + + Request body (RateCalendarRangeUpsertRequest): + + { + "from": "2026-02-05", + "to": "2026-02-10", + "rate": 5200 + } + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 400 Bad Request (invalid date/range) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (rate plan) + + +- List rate calendar API is this one: + + GET /properties/{propertyId}/rate-plans/{ratePlanId}/calendar + + What it does: + + - Returns average rate stats for date range. + + Request body: + + - None. + + Query params: + + - from=YYYY-MM-DD + - to=YYYY-MM-DD + + - Allowed roles: property member. + + Error Codes + + - 400 Bad Request (invalid date/range) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found + + +- Delete rate calendar date API is this one: + + DELETE /properties/{propertyId}/rate-plans/{ratePlanId}/calendar/{rateDate} + + What it does: + + - Deletes one date override. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 400 Bad Request (invalid date) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (rate plan) + +================================================================================ +RAZORPAY APIS +================================================================================ + +- Get Razorpay settings API is this one: + + GET /properties/{propertyId}/razorpay-settings + + What it does: + + - Returns masked configuration status flags. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + + +- Upsert Razorpay settings API is this one: + + PUT /properties/{propertyId}/razorpay-settings + + What it does: + + - Creates/updates Razorpay keys and mode. + + Request body (RazorpaySettingsUpsertRequest): + + { + "keyId": "rzp_live_xxx", + "keySecret": "secret", + "webhookSecret": "whsec", + "isTest": false + } + + - Allowed roles: ADMIN + + Error Codes + + - 400 Bad Request (partial key pair / missing required keys) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (property) + + +- Razorpay webhook API is this one: + + POST /properties/{propertyId}/razorpay/webhook + + What it does: + + - Captures webhook payload. + - Verifies signature. + - Updates QR/link status and inserts payment ledger entries for captured/refund events. + + Request body: + + - Raw Razorpay webhook JSON + + - Allowed roles: Public endpoint (signature mandatory). + + Error Codes + + - 401 Unauthorized (missing/invalid signature) + - 404 Not Found (property) + - 400 Bad Request (settings/webhook secret not configured) + + +- Razorpay return success API is this one: + + POST /properties/{propertyId}/razorpay/return/success + + What it does: + + - No-op redirect receiver. + + Request body: + + - None. + + - Allowed roles: Public endpoint. + + Error Codes + + - 500 Internal Server Error (unexpected) + + +- Razorpay return failure API is this one: + + POST /properties/{propertyId}/razorpay/return/failure + + What it does: + + - No-op redirect receiver. + + Request body: + + - None. + + - Allowed roles: Public endpoint. + + Error Codes + + - 500 Internal Server Error (unexpected) + + +- Create Razorpay QR API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr + + What it does: + + - Creates single-use Razorpay QR for booking amount. + - Reuses latest active QR for same amount when possible. + + Request body (RazorpayQrGenerateRequest): + + { + "amount": 1000, + "expirySeconds": 600 + } + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 400 Bad Request (settings missing / amount invalid / booking inactive) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (booking) + - 502 Bad Gateway (Razorpay failure) + + +- Active Razorpay QR API is this one: + + GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/active + + What it does: + + - Returns current active QR (if any). + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (booking) + + +- Close active Razorpay QR API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/close + + What it does: + + - Closes latest active QR for booking. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 400 Bad Request (settings missing) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (booking) + - 502 Bad Gateway (Razorpay close failure) + + +- Close Razorpay QR by id API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/{qrId}/close + + What it does: + + - Closes specific QR id. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 400 Bad Request (settings missing) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (booking/QR) + - 502 Bad Gateway + + +- Razorpay QR events API is this one: + + GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/{qrId}/events + + What it does: + + - Returns webhook-derived event timeline for QR. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + + +- Razorpay QR events stream API is this one: + + GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/{qrId}/events/stream + + What it does: + + - SSE stream of QR events. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + + +- List Razorpay QRs API is this one: + + GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr + + What it does: + + - Lists QR requests for booking. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (booking) + + +- Create Razorpay payment link API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/payment-link + + What it does: + + - Creates Razorpay payment link. + - Reuses existing open link for same amount when possible. + + Request body (RazorpayPaymentLinkCreateRequest): + + { + "amount": 1000, + "description": "Booking payment", + "viaSms": true + } + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 400 Bad Request (settings missing / amount invalid / booking inactive) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (booking) + - 502 Bad Gateway + + +- List open Razorpay requests API is this one: + + GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/requests + + What it does: + + - Returns open QR and payment-link requests. + + Request body: + + - None. + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (booking) + + +- Close Razorpay request API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/close + + What it does: + + - Closes either QR or payment link by id. + + Request body (RazorpayPaymentRequestCloseRequest): + + { + "qrId": "qr_xxx" + } + + What it does (validation rule): + + - Exactly one of qrId or paymentLinkId is required. + + - Allowed roles: ADMIN, MANAGER, STAFF + + Error Codes + + - 400 Bad Request (bad payload / settings missing) + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (booking/request) + - 502 Bad Gateway + + +- Razorpay refund API is this one: + + POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/refund + + What it does: + + - Sends refund request to Razorpay for a captured online payment. + + Request body (RazorpayRefundRequest): + + { + "paymentId": "uuid", + "amount": 500, + "notes": "Partial refund" + } + + - Allowed roles: ADMIN, MANAGER, FINANCE + + Error Codes + + - 400 Bad Request + - paymentId required + - amount must be > 0 and <= payment amount + - payment missing gateway id + - non-Razorpay payment + - settings missing + - 401 Unauthorized + - 403 Forbidden + - 404 Not Found (booking/payment) + - 502 Bad Gateway + +================================================================================ +END OF FILE +================================================================================ + +Note: +- This file intentionally uses plain text (no markdown). +- It documents current implemented endpoints from controller code only. +- /properties/{propertyId}/room-stays/{roomStayId}/change-rate is not implemented in current code.