openapi: 3.0.3
# Source: https://confluence.webpower.ru/pages/viewpage.action?pageId=491864650 (version 7)
# The HTTP payload uses the shared monolith envelope around ResolveStaticResponse.
info:
  title: Dictionary Static API
  version: 1.0.0
  description: |
    External API for property static data enrichment in SPO GetResults pipeline.
    The API is batch-oriented and returns only found objects.
paths:
  /api/json/hotels/getPropertiesInfo:
    post:
      operationId: resolveStaticProperties
      summary: Resolve static dictionary data by property IDs
      description: |
        Returns static dictionary payload for requested `propertyIds`.
        Missing IDs are silently skipped in response (`items` contains only found entries).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ResolveStaticRequest'
      responses:
        '200':
          description: Static payload for found properties
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetPropertiesInfoResponse'
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '405':
          description: Method not allowed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

components:
  schemas:
    Envelope:
      type: object
      required: [success, errors, actions, platform, uuid, timestamp]
      properties:
        success:
          type: boolean
        errors:
          type: array
          items:
            type: string
        actions:
          type: array
          items:
            type: string
        platform:
          type: string
        uuid:
          type: string
          format: uuid
          x-go-name: UUID
          x-go-type: googleuuid.UUID
          x-go-type-import:
            path: github.com/google/uuid
            name: googleuuid
        timestamp:
          type: integer
          format: int64

    ErrorResponse:
      type: object
      additionalProperties: false
      required: [success, data, errors, actions, platform, uuid, timestamp]
      properties:
        success:
          type: boolean
          enum: [false]
        data:
          type: object
          nullable: true
        errors:
          type: array
          items:
            type: string
        actions:
          type: array
          items:
            type: string
        platform:
          type: string
        uuid:
          type: string
          format: uuid
          x-go-name: UUID
          x-go-type: googleuuid.UUID
          x-go-type-import:
            path: github.com/google/uuid
            name: googleuuid
        timestamp:
          type: integer
          format: int64

    GetPropertiesInfoResponse:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          required: [success, data]
          properties:
            success:
              type: boolean
              enum: [true]
            data:
              $ref: '#/components/schemas/ResolveStaticResponse'

    ResolveStaticRequest:
      type: object
      additionalProperties: false
      required:
        - propertyIds
      properties:
        propertyIds:
          x-go-name: PropertyIDs
          type: array
          x-go-type-skip-optional-pointer: true
          x-omitempty: false
          description: Property IDs used by SPO (`GetResultsResponse.Property.property_id`, UUID).
          minItems: 1
          uniqueItems: true
          items:
            type: string
            format: uuid
            pattern: '^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$'
            x-go-type: googleuuid.UUID
            x-go-type-import:
              path: github.com/google/uuid
              name: googleuuid
        isActive:
          type: boolean
          description: |
            Optional active filter:
            - true: return only active properties
            - false: return only inactive properties
            - omitted: return both active and inactive

    ResolveStaticResponse:
      type: object
      additionalProperties: false
      required:
        - items
      properties:
        items:
          type: array
          x-go-type-skip-optional-pointer: true
          x-omitempty: false
          description: Found properties only.
          items:
            $ref: '#/components/schemas/DictionaryProperty'

    DictionaryProperty:
      type: object
      additionalProperties: false
      required:
        - propertyId
        - isActive
        - title
      properties:
        propertyId:
          x-go-name: PropertyID
          type: string
          format: uuid
          pattern: '^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$'
          x-go-type: googleuuid.UUID
          x-go-type-import:
            path: github.com/google/uuid
            name: googleuuid
          description: Join key for SPO merge (UUID).
        sPropertyId:
          x-go-name: SPropertyID
          type: string
          nullable: true
          x-omitempty: false
          description: Internal Sutochno ID in `s<digits>` format.
        isActive:
          type: boolean
          description: Property archival flag.
        title:
          type: string
        type:
          type: string
          nullable: true
          x-omitempty: false
          description: "Localized SPO property type title (current set from dictionary mapping, e.g. 'Отель', 'Апартаменты', 'Квартира', 'Частный дом', 'Комната', 'Койко-место в хостеле')."
        stars:
          type: integer
          format: int32
          nullable: true
          x-omitempty: false
        isSuperhost:
          type: boolean
          nullable: true
          x-omitempty: false
        freeDepositForSuperguest:
          type: boolean
          nullable: true
          x-omitempty: false
        convenientLocation:
          type: boolean
          nullable: true
          x-omitempty: false
        rating:
          nullable: true
          x-omitempty: true
          allOf:
            - $ref: '#/components/schemas/Rating'
        media:
          nullable: true
          x-omitempty: true
          allOf:
            - $ref: '#/components/schemas/Media'
        location:
          nullable: true
          x-omitempty: true
          allOf:
            - $ref: '#/components/schemas/Location'
        rooms:
          type: array
          x-go-type-skip-optional-pointer: true
          x-omitempty: false
          description: |
            Dictionary room categories. SPO matches `UniversalOffer.roomType.id` with `rooms[].id`.
          items:
            $ref: '#/components/schemas/DictionaryRoom'

    DictionaryRoom:
      type: object
      additionalProperties: false
      required:
        - id
      properties:
        id:
          x-go-name: ID
          type: string
        title:
          type: string
          nullable: true
          x-omitempty: false
        properties:
          nullable: true
          x-omitempty: true
          allOf:
            - $ref: '#/components/schemas/RoomProperties'

    RoomProperties:
      type: object
      additionalProperties: false
      properties:
        beds:
          type: integer
          format: int32
          nullable: true
          x-omitempty: false
        area:
          type: integer
          format: int32
          nullable: true
          x-omitempty: false
        rooms:
          type: integer
          format: int32
          nullable: true
          x-omitempty: false
        bedrooms:
          type: integer
          format: int32
          nullable: true
          x-omitempty: false
        maxGuests:
          type: integer
          format: int32
          nullable: true
          x-omitempty: false
        windowViews:
          type: string
          nullable: true
          x-omitempty: false
          enum:
            - EMPTY
            - SEA
            - MOUNTAIN
            - RIVER_LAKE
            - CITY
            - FOREST

    Rating:
      type: object
      additionalProperties: false
      properties:
        value:
          type: number
          format: float
          nullable: true
          x-omitempty: false
        count:
          type: integer
          format: int32

    Media:
      type: object
      additionalProperties: false
      properties:
        images:
          type: array
          x-go-type-skip-optional-pointer: true
          x-omitempty: false
          items:
            $ref: '#/components/schemas/Image'

    Image:
      type: object
      additionalProperties: false
      required:
        - url
      properties:
        url:
          x-go-name: URL
          type: string
        blurHash:
          type: string
          nullable: true
          x-omitempty: false

    Location:
      type: object
      additionalProperties: false
      properties:
        lat:
          type: number
          format: double
          nullable: true
          x-omitempty: false
        lng:
          type: number
          format: double
          nullable: true
          x-omitempty: false
        relations:
          nullable: true
          x-omitempty: true
          allOf:
            - $ref: '#/components/schemas/Relations'
        address:
          nullable: true
          x-omitempty: true
          allOf:
            - $ref: '#/components/schemas/Address'

    Relations:
      type: object
      additionalProperties: false
      properties:
        ropeway:
          type: array
          x-go-type-skip-optional-pointer: true
          x-omitempty: false
          items:
            $ref: '#/components/schemas/Ropeway'
        sea:
          type: array
          x-go-type-skip-optional-pointer: true
          x-omitempty: false
          items:
            $ref: '#/components/schemas/Sea'
        metro:
          type: array
          x-go-type-skip-optional-pointer: true
          x-omitempty: false
          items:
            $ref: '#/components/schemas/Metro'

    Ropeway:
      type: object
      additionalProperties: false
      properties:
        title:
          type: string
        distance:
          type: integer
          format: int32

    Sea:
      type: object
      additionalProperties: false
      properties:
        title:
          type: string
        distance:
          type: integer
          format: int32
        name:
          type: string
        firstLine:
          type: boolean

    Metro:
      type: object
      additionalProperties: false
      properties:
        title:
          type: string
        distance:
          type: integer
          format: int32
        walkTime:
          type: integer
          format: int32
        lineColor:
          type: string

    Address:
      type: object
      additionalProperties: false
      properties:
        title:
          type: string
          nullable: true
          x-omitempty: false
        house:
          type: string
          nullable: true
          x-omitempty: false
        country:
          nullable: true
          x-omitempty: true
          allOf:
            - $ref: '#/components/schemas/AddressEntity'
        region:
          nullable: true
          x-omitempty: true
          allOf:
            - $ref: '#/components/schemas/AddressEntity'
        city:
          nullable: true
          x-omitempty: true
          allOf:
            - $ref: '#/components/schemas/AddressEntity'
        place:
          nullable: true
          x-omitempty: true
          allOf:
            - $ref: '#/components/schemas/AddressEntity'
        streetType:
          nullable: true
          x-omitempty: true
          allOf:
            - $ref: '#/components/schemas/AddressEntity'
        street:
          nullable: true
          x-omitempty: true
          allOf:
            - $ref: '#/components/schemas/AddressEntity'

    AddressEntity:
      type: object
      additionalProperties: false
      properties:
        id:
          x-go-name: ID
          type: string
          nullable: true
          x-omitempty: false
        title:
          type: string
          nullable: true
          x-omitempty: false
