openapi: 3.0.3
info:
  title: Mas Stock API
  description: API for stock retailers management and reservations
  contact:
    name: MasStock Squad
    email: mas_stock@masmovil.com
  version: 1.0.0
servers:
  - url: 'http://localhost:8080/v1/'
    description: Local Development
  - url: 'https://mas-stock.sta.masstack.com/v1/'
    description: Staging
  - url: 'https://stock.masstack.com/v1/'
    description: Production
tags:
  - name: Stock Reservations
    description: Operations with stock reservations for retailers
paths:
  /orgs/{orgId}/reservation:
    post:
      tags:
        - Stock Reservations
      summary: Create a reservation
      description: Creates a new reservation for a device
      operationId: 'createReservation'
      parameters:
        - name: orgId
          in: path
          description: Organization name as it is registered in mas-stack
          required: true
          schema:
            type: string
          example: yoigo
      requestBody:
        description: Reservation request with device details
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReservationRequest'
        required: true
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReservationResponse'
              example:
                reservation_id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
        400:
          description: Bad Request - Missing mandatory fields, validation error, or device validation failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                validation_error:
                  summary: Missing required field
                  value:
                    code: "VALIDATION_ERROR"
                    message: "dealer_id is required"
                    details: null
                device_not_related:
                  summary: Device not associated with dealer (SIM only)
                  value:
                    code: "BAD_REQUEST"
                    message: "device_id not related with dealer_id"
                    details: null
                device_not_reservable:
                  summary: Device in non-reservable status (SIM only)
                  value:
                    code: "BAD_REQUEST"
                    message: "device_id is in a non reservable status"
                    details: null
        404:
          description: Not Found - Device not found in external systems
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: "NOT_FOUND"
                message: "device_id not found"
                details: null
        409:
          description: Conflict - Reservation already exists for this device with CREATED status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReservationConflictError'
              example:
                code: "RESERVATION_CONFLICT"
                message: "Reservation already exists for device DEVICE123 with status CREATED, created by dealer DEALER001"
                device_id: "DEVICE123"
                dealer_id: "DEALER001"
                status: "CREATED"
        500:
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: "INTERNAL_ERROR"
                message: "Internal server error"
                details: null
        503:
          description: Service Unavailable - Database persistence error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: "DATABASE_ERROR"
                message: "Unable to persist reservation data"
                details: "The reservation could not be saved to the database. Please try again later."
  /orgs/{orgId}/reservation/{reservation_id}/cancellation:
    post:
      tags:
        - Stock Reservations
      summary: Cancel a reservation
      description: Cancels an existing reservation by its ID. Validates that the dealer requesting cancellation matches the dealer who created the reservation.
      operationId: 'cancelReservation'
      parameters:
        - name: orgId
          in: path
          description: Organization name as it is registered in mas-stack
          required: true
          schema:
            type: string
          example: yoigo
        - name: reservation_id
          in: path
          description: Reservation identifier
          required: true
          schema:
            type: string
            format: uuid
          example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
      requestBody:
        description: Cancellation request with dealer information
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CancellationRequest'
        required: true
      responses:
        200:
          description: Success - Reservation cancelled successfully
        400:
          description: Bad Request - Dealer cannot cancel reservation created by another dealer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: "DEALER_MISMATCH"
                message: "Dealer DEALER002 cannot cancel reservation created by dealer DEALER001"
                details: null
        404:
          description: Not Found - Reservation not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: "RESERVATION_NOT_FOUND"
                message: "Reservation with ID a1b2c3d4-e5f6-7890-abcd-ef1234567890 not found"
                details: null
        500:
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: "INTERNAL_ERROR"
                message: "Internal server error"
                details: null
  /orgs/{orgId}/device:
    get:
      tags:
        - Stock Reservations
      summary: Get device information
      description: Retrieves device information by identifier
      operationId: 'getDevice'
      parameters:
        - name: orgId
          in: path
          description: Organization name as it is registered in mas-stack
          required: true
          schema:
            type: string
          example: yoigo
        - name: identifier
          in: query
          description: Device identifier
          required: true
          schema:
            type: string
          example: "DEVICE123456"
      responses:
        200:
          description: Success - Device information retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeviceResponse'
              example:
                reference: "REF123456"
                mac: "00:1A:2B:3C:4D:5E"
        404:
          description: Not Found - Device not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: "DEVICE_NOT_FOUND"
                message: "Device with identifier DEVICE123456 not found"
                details: null
        500:
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: "INTERNAL_ERROR"
                message: "Internal server error"
                details: null
components:
  schemas:
    ReservationRequest:
      type: object
      required:
        - device_id
        - dealer_id
        - is_sim
      properties:
        device_id:
          type: string
          description: Device identifier
          example: "DEVICE123456"
        dealer_id:
          type: string
          description: Dealer identifier
          example: "DEALER001"
        is_sim:
          type: boolean
          description: Indicates if the reservation is for a SIM card
          example: true
    ReservationResponse:
      type: object
      properties:
        reservation_id:
          type: string
          format: uuid
          description: Generated reservation identifier in UUID format
          example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    CancellationRequest:
      type: object
      required:
        - dealer
      properties:
        dealer:
          type: string
          description: Dealer identifier requesting the cancellation
          example: "DEALER001"
    DeviceResponse:
      type: object
      required:
        - reference
      properties:
        reference:
          type: string
          description: Device reference
          example: "REF123456"
        mac:
          type: string
          description: MAC address (optional)
          example: "00:1A:2B:3C:4D:5E"
    Error:
      type: object
      properties:
        code:
          type: string
          example: "ERROR_CODE"
        message:
          type: string
          example: "Error message"
        details:
          type: string
          description: Additional error details
    ReservationConflictError:
      type: object
      properties:
        code:
          type: string
          example: "RESERVATION_CONFLICT"
        message:
          type: string
          example: "Reservation already exists for device"
        reservation_id:
          type: string
          format: uuid
          description: Existing reservation identifier
          example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
        device_id:
          type: string
          description: Device identifier that has the conflict
          example: "DEVICE123"
        dealer_id:
          type: string
          description: Dealer who created the existing reservation
          example: "DEALER001"
        status:
          type: string
          description: Current status of the existing reservation
          enum: [CREATED, CANCELLED, FINALIZED]
          example: "CREATED"
