openapi: 3.0.3
info:
  title: GRN Hotel Booking API
  description: |
    Internal API wrapper for GRN Hotel Booking flow.
    Includes booking lifecycle and static master data
    (countries, cities, currencies, hotels).
  version: 1.0.0

servers:
  - url: https://all.flightapi.co.in/grnc-hotels/api
    description: Production
  - url: http://localhost:3000/api
    description: Local

tags:
  - name: Static
  - name: Search
  - name: Markup
  - name: Availability
  - name: Recheck
  - name: Booking
  - name: Cancellation

paths:

# ========================= STATIC =========================

  /static/countries:
    get:
      tags: [Static]
      summary: Get all countries
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  countries:
                    type: array
                    items:
                      $ref: '#/components/schemas/Country'

  /static/countries/{code}:
    get:
      tags: [Static]
      summary: Get country by ISO2 or ISO3
      parameters:
        - name: code
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Country'

  /static/cities:
    get:
      tags: [Static]
      summary: Get cities
      parameters:
        - name: country
          in: query
          schema: { type: string }
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  cities:
                    type: array
                    items:
                      $ref: '#/components/schemas/City'

  /static/cities/{code}:
    get:
      tags: [Static]
      summary: Get city by code
      parameters:
        - name: code
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/City'

  /static/currencies:
    get:
      tags: [Static]
      summary: Get all currencies
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  currencies:
                    type: array
                    items:
                      $ref: '#/components/schemas/Currency'

  /static/currencies/{code}:
    get:
      tags: [Static]
      summary: Get currency by code
      parameters:
        - name: code
          in: path
          required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Currency'

  /static/hotels:
    get:
      tags: [Static]
      summary: Get hotels from database
      parameters:
        - name: country
          in: query
        - name: city
          in: query
        - name: q
          in: query
        - name: limit
          in: query
          schema: { type: integer, default: 50 }
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  hotels:
                    type: array
                    items:
                      $ref: '#/components/schemas/Hotel'

# ========================= SEARCH =========================

  /booking/search:
    post:
      tags: [Search]
      summary: Search hotels by city or country
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchRequest'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'

  /booking-markup/hotel-list:
    post:
      tags: [Markup]
      summary: Hotel list with markup breakdown (GRN)
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchRequest'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MarkupHotelListResponse'

  /booking/refetch/{search_id}:
    get:
      tags: [Availability]
      summary: Re-fetch availability
      parameters:
        - name: search_id
          in: path
          required: true
        - name: rates
          in: query
          schema:
            type: string
            enum: [concise, comprehensive]
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'

# ========================= RECHECK =========================

  /booking/recheck:
    post:
      tags: [Recheck]
      summary: Rate recheck
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecheckRequest'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecheckResponse'

# ========================= BOOKING =========================

  /booking/book:
    post:
      tags: [Booking]
      summary: Confirm booking
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BookingRequest'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookingResponse'

# ========================= FETCH BOOKING =========================

  /booking/fetch/grn/{booking_id}:
    get:
      tags: [Booking]
      summary: Fetch booking by booking id (booking_uid value)
      security:
        - bearerAuth: []
      parameters:
        - name: booking_id
          in: path
          required: true
          schema:
            type: string
        - name: type
          in: query
          schema:
            type: string
            default: GRN
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookingStatusResponse'

# ========================= CANCELLATION =========================

  /booking/cancel/{booking_reference}:
    delete:
      tags: [Cancellation]
      summary: Cancel a booking
      parameters:
        - name: booking_reference
          in: path
          required: true
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CancellationRequest'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CancellationResponse'


  /static/availability/list:
    post:
      tags: [Availability]
      summary: List available GRE hotels from cache (DB)
      description: >
        Returns available GRE hotels and prices from database.
        Data is populated during GRE Search API calls.
        No live GRE API call is made here.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GreAvailabilityListRequest'
      responses:
        '200':
          description: Available GRE hotels list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GreAvailabilityListResponse'
        '400':
          description: Bad request
        '500':
          description: Server error


  /booking/list:
    get:
      tags:
        - Bookings
      summary: Get hotel booking list
      description: Fetch booking list from GRN based on filters like booking date, travel date, pagination, etc.
      parameters:
        - in: query
          name: filter_type
          schema:
            type: string
            example: booking_date
          description: Filter type (booking_date or travel_date)

        - in: query
          name: start
          schema:
            type: string
            format: date
            example: 2026-02-01
          description: Start date (required with end)

        - in: query
          name: end
          schema:
            type: string
            format: date
            example: 2026-02-05
          description: End date (required with start)

        - in: query
          name: from
          schema:
            type: integer
            example: 0
          description: Pagination starting index

        - in: query
          name: count
          schema:
            type: integer
            example: 20
          description: Number of records to fetch (required with from)

        - in: query
          name: direction
          schema:
            type: string
            enum: [next, prev]
            example: next
          description: Sort direction (required with from)

        - in: query
          name: type
          schema:
            type: string
            example: B
          description: Booking status/type filter (Booking - B / Cancel - C)

      responses:
        '200':
          description: Successful booking list fetch
          content:
            application/json:
              schema:
                type: object

        '400':
          description: Invalid request parameters

        '500':
          description: Server error

  /booking/blist:
    post:
      tags:
        - Booking
      summary: Get agent hotel booking list (from database)
      description: |
        Returns hotel bookings stored in the system for the logged-in agent.
        Data is read from the local bookings table (no supplier API call).
        Supports filtering by booking date, check-in date, or check-out date.
      security:
        - bearerAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BookingBListRequest'
            example:
              filter_type: booking_date
              start: "2026-02-01"
              end: "2026-02-05"
              from: 100
              count: 20
              direction: next
      responses:
        '200':
          description: Booking list fetched successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookingBListRequest'
        '400':
          description: Invalid request parameters
        '401':
          description: Unauthorized agent
        '500':
          description: Server error


# ========================= SCHEMAS =========================

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  schemas:

    Country:
      type: object
      properties:
        code: { type: string }
        iso3: { type: string }
        name: { type: string }

    City:
      type: object
      properties:
        city_code: { type: string }
        city_name: { type: string }
        country_code: { type: string }

    Currency:
      type: object
      properties:
        currency_code: { type: string }
        currency_name: { type: string }
        country_code: { type: string }

    Hotel:
      type: object
      properties:
        hotel_code: { type: string }
        hotel_name: { type: string }
        city_code: { type: string }
        country_code: { type: string }

    SearchRequest:
      type: object
      required: [checkin, checkout, client_nationality, rooms]
      properties:
        city: { type: string }
        country: { type: string }
        hotel_code: { type: string }
        checkin: { type: string }
        checkout: { type: string }
        client_nationality: { type: string }
        currency: { type: string }
        rooms:
          type: array
          items:
            type: object
            properties:
              adults: { type: integer }
              children_ages:
                type: array
                items: { type: integer }

    SearchResponse:
      type: object
      properties:
        search_uid: { type: string }
        data: { type: object }

    MarkupHotelListResponse:
      type: object
      properties:
        status: { type: string, example: "SUCCESS" }
        hotels_found: { type: integer }
        data:
          type: array
          items:
            $ref: '#/components/schemas/MarkupHotel'

    MarkupHotel:
      type: object
      properties:
        hotel_id: { type: string }
        vendor_id: { type: integer }
        hotel_name: { type: string }
        hotel_image: { type: string }
        description: { type: string }
        address: { type: string }
        city: { type: string }
        state: { type: string }
        country: { type: string }
        postal_code: { type: string }
        lt: { type: string }
        ln: { type: string }
        rating: { type: integer }
        property_type: { type: string }
        noOfdays: { type: integer }
        noOfRooms: { type: integer }
        checkin_time: { type: string }
        checkout_time: { type: string }
        currency: { type: string }
        totalroomPrice: { type: number }
        MR: { type: number }
        rooms:
          type: array
          items:
            $ref: '#/components/schemas/MarkupRoom'
        source:
          type: array
          items: { type: string }

    MarkupRoom:
      type: object
      properties:
        id: { type: integer }
        rc: { type: string }
        rt: { type: string }
        adt: { type: integer }
        chd: { type: integer }
        extra_pax_allowed: { type: integer }
        MB: { type: object }
        tp: { type: number }
        currency: { type: string }
        image: { type: string }
        desc: { type: string }
        bed_type: { type: string }
        room_size: { type: number }
        zero_cancellation: { type: integer }
        cancellation_hours: { type: integer }
        child_age_restriction: { type: integer }
        hotel_contact: { type: string }
        hotel_email: { type: string }
        room_cancellation_policies:
          type: array
          items: { type: object }
        noOfRooms: { type: integer }
        roomPrice: { type: number }
        purchese_price: { type: number }
        org_purchase_price: { type: number }
        supplier_currency: { type: string }
        supplier_data: { type: object }
        supplier_contract: { type: object }
        noOfGuest: { type: integer }
        totalRooms: { type: integer }
        availableRooms: { type: integer }
        is_refundable: { type: integer }
        booking_closed: { type: integer }
        availability: { type: string }
        supplier: { type: object }
        org_roomPrice: { type: number }

    RecheckRequest:
      type: object
      properties:
        search_id: { type: string }
        rate_key: { type: string }
        group_code: { type: string }

    RecheckResponse:
      type: object
      properties:
        hotel: { type: object }

    BookingRequest:
      type: object
      required:
        - search_id
        - hotel_code
        - city_code
        - group_code
        - checkin
        - checkout
        - payment_type
        - holder
        - booking_items
      properties:
        search_id: { type: string }
        hotel_code: { type: string }
        city_code: { type: string }
        group_code: { type: string }
        checkin: { type: string }
        checkout: { type: string }
        payment_type:
          type: string
          enum: [AT_WEB]
        holder:
          $ref: '#/components/schemas/Holder'
        booking_items:
          type: array
          items:
            $ref: '#/components/schemas/BookingItem'

    Holder:
      type: object
      properties:
        title: { type: string }
        name: { type: string }
        surname: { type: string }
        client_nationality: { type: string }
        email: { type: string }
        phone_number: { type: string }
        pan_number: { type: string }
        pan_company_name: { type: string }

    BookingItem:
      type: object
      properties:
        rate_key: { type: string }
        room_code: { type: string }
        rooms:
          type: array
          items:
            $ref: '#/components/schemas/Room'

    Room:
      type: object
      properties:
        room_reference: { type: string }
        paxes:
          type: array
          items:
            $ref: '#/components/schemas/Pax'

    Pax:
      type: object
      properties:
        title: { type: string }
        name: { type: string }
        surname: { type: string }
        type:
          type: string
          enum: [AD, CH]
        age: { type: string }

    BookingResponse:
      type: object
      properties:
        status: { type: string }
        booking_uid: { type: string }
        data: { type: object }

    CancellationRequest:
      type: object
      properties:
        comments: { type: string }
        reason: { type: integer }

    CancellationResponse:
      type: object
      properties:
        status: { type: string }
        cancellation_uid: { type: string }
        data: { type: object }

    # -------- GRE Availability List (DB Based) --------
    GreAvailabilityListRequest:
      type: object
      required: [city_name, checkin, checkout]
      properties:
        city_name:
          type: string
          example: "Pattaya"
        checkin:
          type: string
          format: date
          example: "2026-01-28"
        checkout:
          type: string
          format: date
          example: "2026-01-29"
        numberOfAdults:
          type: integer
          example: 2
          default: 1
        numberOfChild:
          type: integer
          example: 0
          default: 0

    GreAvailabilityListResponse:
      type: object
      properties:
        status:
          type: string
          example: SUCCESS
        total:
          type: integer
          example: 8
        hotels:
          type: array
          items:
            type: object
            properties:
              id:
                type: integer
                example: 901
              hotel_code:
                type: string
                example: "GRE12345"
              hotel_name:
                type: string
                example: "GRE Grand Palace"
              images:
                type: array
                items:
                  type: string
              address:
                type: string
                example: "MG Road, Bengaluru"
              city_name:
                type: string
                example: "Bengaluru"
              country_name:
                type: string
                example: "India"
              hotel_rating:
                type: integer
                example: 5
              min_price:
                type: number
                example: 5100
              currency:
                type: string
                example: "INR"
              last_checked_at:
                type: string
                format: date-time
                example: "2026-01-23T11:10:00Z"
              source:
                type: string
                example: "GRE"

    BookingBListRequest:
      type: object
      properties:
        filter_type:
          type: string
          enum: [booking_date, checkin_date, checkout_date]
          default: booking_date
        start:
          type: string
          format: date
          example: "2026-02-01"
        end:
          type: string
          format: date
          example: "2026-02-05"
        from:
          type: integer
          example: 100
          description: Booking ID cursor for pagination
        count:
          type: integer
          default: 20
        direction:
          type: string
          enum: [next, prev]
          default: next

    BookingStatusRequest:
      type: object
      properties:
        booking_reference: { type: string }
        booking_uid: { type: string }
        booking_id: { type: string }

    BookingStatusResponse:
      type: object
      properties:
        booking_id: { type: string }
        booking_reference: { type: string }
        status: { type: string }
        hotel_name: { type: string }
        hotel_address: { type: string }
        latitude: { type: number }
        longitude: { type: number }
        checkin: { type: string, format: date }
        checkout: { type: string, format: date }
        booked_on: { type: string, format: date-time }
        sale_amount: { type: number }
        currency: { type: string }
        guest_count: { type: integer }
        room_details:
          type: array
          items: { type: object }
        traveler_details:
          type: object
          properties:
            holder: { type: object }
            paxes:
              type: array
              items: { type: object }
