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: 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/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
      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_reference}:
    get:
      tags: [Booking]
      summary: Fetch booking by GRN reference
      parameters:
        - name: booking_reference
          in: path
          required: true
        - name: type
          in: query
          schema:
            type: string
            default: GRN
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object

# ========================= 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'


  /gre/hotels/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

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

components:
  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 }
        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 }

    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_code, checkin, checkout]
      properties:
        city_code:
          type: string
          example: "DEL"
        checkin:
          type: string
          format: date
          example: "2026-03-20"
        checkout:
          type: string
          format: date
          example: "2026-03-22"
        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"
