openapi: 3.0.0
info:
  description: |
    API de la Heladería Via Apilia. A través de esta API se pueden consultar
    los gustos de helado y realizar pedidos.
  version: "1.0.0"
  title: Heladería Via Apilia
  contact:
    email: [email protected]
  license:
    name: Apache 2.0
    url: '<http://www.apache.org/licenses/LICENSE-2.0.html>'
servers:
  - url: '<https://api.heladeria-apilia.com>'
paths:
  /gustos:
    get:
      description: Listar los gustos de helado
      parameters:
      - in: query
        name: tipo
        required: false
        schema:
          $ref: '#/components/schemas/TipoDeGusto'
      responses:
        '200':
          description: Estos son los gustos de helado
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Gusto'
  /gustos/{gustoId}:
    get:
      description: Ver un gusto particular
      parameters:
      - $ref: '#/components/parameters/gustoId'
      responses:
        '200':
          description: El gusto seleccionado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Gusto'
        '404':
          description: No se conoce un gusto con tal id
  /pedidos:
    post:
      description: Crear un nuevo pedido a la dirección indicada
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                direccion_entrega:
                  type: string
                  description: dirección en la que se ha de entregar este pedido
              required: [direccion_entrega]
      responses:
        '201':
          description: El pedido ha sido creado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pedido'
  /pedidos/{pedidoId}:
    get:
      description: Ver un pedido particular
      parameters:
      - $ref: '#/components/parameters/pedidoId'
      responses:
        '200':
          description: El pedido ha sido hallado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pedido'
        '404':
          description: No se conoce un pedido con tal id
    put:
      description: Cambiar los datos de un pedido particular
      parameters:
      - $ref: '#/components/parameters/pedidoId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                direccion_entrega:
                  type: string
                  description: dirección en la que se ha de entregar este pedido
              required: [direccion_entrega]
      responses:
        '200':
          description: El pedido ha sido actualizado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pedido'
        '404':
          description: No se conoce un pedido con tal id
  /pedidos/{pedidoId}/potes:
    get:
      description: Lista los potes que componen un pedido
      parameters:
      - $ref: '#/components/parameters/pedidoId'
      responses:
        '200':
          description: Los potes del pedido
          content:
            application/json:
              schema:
                type: array
                items: 
                  $ref: '#/components/schemas/Pote'
        '404':
          description: No se conoce un pedido con tal id
    post:
      description: Agrega un pote a un pedido
      parameters:
      - $ref: '#/components/parameters/pedidoId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                peso:
                  $ref: '#/components/schemas/PesoDePote'
                gustos:
                  type: array
                  items:
                    type: string
                  description: los gustos de helado en este pote
                  example: [ddl, pist]
              required: [peso, gustos]
      responses:
        '201':
          description: El pote fue agregado al pedido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pote'
        '404':
          description: No se conoce un pedido con tal id
  /pedidos/{pedidoId}/potes/{poteId}:
    delete:
      description: quitar un pote de un pedido
      parameters:
      - $ref: '#/components/parameters/pedidoId'
      - $ref: '#/components/parameters/poteId'
      responses:
        '204':
          description: El pote fue quitado del pedido
        '404':
          description: No se conoce un pedido y/o pote con tal id
  /pedidos/{pedidoId}/pagar:
    post:
      description: Inicia el pago del pedido
      parameters:
      - $ref: '#/components/parameters/pedidoId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DatosDePago'
      responses:
        '202':
          description: Los datos de pago han sido recibidos y serán procesados
        '404':
          description: No se conoce un pedido con tal id
  /pedidos/{pedidoId}/pago:
    get:
      description: Ver el estado del pago de un pedido particular
      parameters:
      - $ref: '#/components/parameters/pedidoId'
      responses:
        '200':
          description: Este es el estado del pago del pedido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pago'
        '404':
          description: No se conoce un pedido con tal id
  /pedidos/{pedidoId}/repartidor:
    put:
      description: Cambiar el repartidor de un pedido particular
      parameters:
      - $ref: '#/components/parameters/pedidoId'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                repartidorId:
                  type: integer
                  description: ID del repartidor al que se le desea asociar el pedido
                  example: 3
              required: [repartidorId]
      responses:
        '200':
          description: El pedido ha sido actualizado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pedido'
        '404':
          description: No se conoce un pedido con tal ID
    delete:
      description: quitar al repartidor asignado del pedido
      parameters:
      - $ref: '#/components/parameters/pedidoId'
      responses:
        '204':
          description: El repartidor fue quitado del pedido
        '404':
          description: No se conoce un pedido con tal ID
  /repartidores:
    get:
      description: Listar los repartidores existentes
      parameters:
      - in: query
        name: edad
        required: false
        schema:
          $ref: '#/components/schemas/EdadRepartidor'
      responses:
        '200':
          description: Estos son los repartidores existentes
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Repartidor'
    post:
      description: Crear un nuevo repartidor
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Repartidor'
      responses:
        '201':
          description: El repartidor ha sido creado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Repartidor'
  /repartidores/{repartidorId}:
    put:
      description: Cambiar los datos de un repartidor particular
      parameters:
      - $ref: '#/components/parameters/repartidorId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Repartidor'
      responses:
        '200':
          description: El repartidor ha sido actualizado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Repartidor'
        '404':
          description: No se conoce un repartidor con tal ID
    delete:
      description: eliminar un repartidor
      parameters:
      - $ref: '#/components/parameters/repartidorId'
      responses:
        '204':
          description: El repartidor ha sido borrado
        '404':
          description: No se conoce un repartidor con tal ID
  /repartidores/{repartidorId}/vehiculos:
    get:
      description: Lista los vehículos asociados a un repartidor
      parameters:
      - $ref: '#/components/parameters/repartidorId'
      responses:
        '200':
          description: Los vehículos del repartidor
          content:
            application/json:
              schema:
                type: array
                items: 
                  $ref: '#/components/schemas/Vehiculo'
        '404':
          description: No se conoce un repartidor con tal ID
    post:
      description: Agrega un vehículo a un repartidor
      parameters:
      - $ref: '#/components/parameters/repartidorId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Vehiculo'
      responses:
        '201':
          description: El vehículo fue agregado al repartidor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Vehiculo'
        '404':
          description: No se conoce un repartidor con tal ID 
  /repartidores/{repartidorId}/vehiculos/{vehiculoId}:
    delete:
      description: quitar un vehículor de un repartidor
      parameters:
      - $ref: '#/components/parameters/repartidorId'
      - $ref: '#/components/parameters/vehiculoId'
      responses:
        '204':
          description: El vehículo fue quitado del repartidor exitosamente
        '404':
          description: No se conoce un repartidor y/o vehículo con tal ID
    put:
      description: Cambiar los datos de un vehículo particular
      parameters:
      - $ref: '#/components/parameters/repartidorId'
      - $ref: '#/components/parameters/vehiculoId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Vehiculo'
      responses:
        '200':
          description: El vehículo ha sido actualizado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Vehiculo'
        '404':
          description: No se conoce un vehículo con tal ID
components:
  parameters:
    gustoId:
      name: gustoId
      in: path
      description: id del gusto
      required: true
      schema:
        type: string
    pedidoId:
      name: pedidoId
      in: path
      description: id del pedido
      required: true
      schema:
        type: integer
    poteId:
      name: poteId
      in: path
      description: id del pote
      required: true
      schema:
        type: integer
    repartidorId:
      name: repartidorId
      in: path
      description: ID del repartidor
      required: true
      schema:
        type: integer
    vehiculoId:
      name: vehiculoId
      in: path
      required: true
      description: ID del vehículo
      schema:
        type: integer
  schemas:
    TipoDeGusto:
      description: categoría de gustos de helado
      type: string
      enum:
        - chocolates
        - dulce de leches
        - cremas
        - frutas
      example: dulce de leches
    Gusto:
      description: un gusto de helado
      type: object
      properties:
        id:
          type: string
          description: nombre corto que identifica este gusto
          example: ddl
        nombre:
          type: string
          description: nombre legible por humanos para este gusto
          example: Dulce de leche
        tipo:
          $ref: '#/components/schemas/TipoDeGusto'
      required: [id, nombre, tipo]
    Pedido:
      description: un pedido de helados
      type: object
      properties:
        id:
          type: integer
          description: identificador de este pedido
          example: 22
        direccion_entrega:
          type: string
          description: dirección en la que se ha de entregar este pedido
          example: Lavalleja 244 4C, CABA
        repartidorId:
          type: integer
          description: ID del repartidor encargado de la entrega
          example: 2
        _links:
          type: object
          description: hypermedia links de un pedido
          properties:
            potes: 
              $ref: '#/components/schemas/Link'
            pagar: 
              $ref: '#/components/schemas/Link'
            pago: 
              $ref: '#/components/schemas/Link'
            repartidor:
              $ref: '#/components/schemas/Link'
      required: [id, direccion_entrega]
    PesoDePote:
      description: peso de un pote de helado en gramos
      type: string
      enum:
        - "1000"
        - "500"
        - "250"
      example: "500"
    Pote:
      description: un pote de helado dentro de un pedido
      type: object
      properties:
        id:
          type: integer
          description: identificador de este pote dentro del pedido
          example: 1
        peso:
          $ref: '#/components/schemas/PesoDePote'
        gustos:
          type: array
          items:
            type: object
            properties:
              id: 
                type: string
                description: el id del gusto de helado en este pote
                example: ddl
              _links:
                type: object
                description: hypermedia links de un gusto dentro de un pote
                properties:
                  self:
                    $ref: '#/components/schemas/Link'
          description: los gustos de helado en este pote
        _links:
          type: object
          description: hypermedia links de un pote
          properties:
            pedido:
              $ref: '#/components/schemas/Link'
            borrar: 
              $ref: '#/components/schemas/Link'
      required: [id, peso, gustos]
    DatosDePago:
      description: los datos necesarios para iniciar el pago de un pedido
      type: object
      discriminator:
        propertyName: tipoDePago
      properties:
        tipoDePago:
          type: string
          description: se usa para determinar el tipo de pago a usar
      required: [tipoDePago]
    DatosDePagoBilleteraVirtual:
      description: datos de pago cuando se usa una billetera virtual
      allOf:
      - $ref: '#/components/schemas/DatosDePago'
      - type: object
        properties:
          alias:
            type: string
            description: nombre de usuario o alias de la billetera a utilizar
            example: mi.cuenta.billetera
        required: [alias]
    DatosDePagoTarjeta:
      description: datos de pago cuando se usa tarjeta de crédito
      allOf:
      - $ref: '#/components/schemas/DatosDePago'
      - type: object
        properties:
          numerosTarjeta:
            type: string
            description: los 15 o 16 números de la tarjeta de crédito
            example: "1234567812345678"
          vencimientoTarjetaMes:
            type: number
            format: int8
            minimum: 1
            maximum: 6
            description: el mes del vencimiento de la tarjeta de crédito
            example: 4
          vencimientoTarjetaAnio:
            type: number
            format: int8
            minimum: 0
            maximum: 99
            description: el año de vencimiento de la tarjeta expresado en dos dígitos
            example: 24
        required: [numerosTarjeta, vencimientoTarjetaMes, vencimientoTarjetaAnio]
    Pago:
      description: estado del pago de un pedido
      type: object
      properties:
        status:
          type: string
          enum:
            - pendiente de pago
            - pago en proceso
            - pago aceptado
            - pago fallado
          example: pago aceptado
      required: [status]
    Link:
      description: un link usado para hypermedia
      type: object
      properties:
        href:
          type: string
          format: uri
          description: la URI del link
          example: "<http://foo.com/bar>"
        verb:
          type: string
          enum:
          - GET
          - POST
          - PUT
          - PATCH
          - DELETE
          example: GET
          description: el verbo a usar en el link
    Repartidor:
      description: empleado encargado de repartir pedidos a los clientes
      type: object
      properties:
        id:
          type: integer
          description: identificador único del repartidor
          readOnly: true
          example: 1
        nombre:
          type: string
          description: nombre del repartidor
          example: Juan Carlos
        apellido: 
          type: string
          description: apellido del repartidor
          example: González
        CUIL:
          type: number
          description: CUIL legal del repartidor
          example: 27378955671
        edad:
          $ref: '#/components/schemas/EdadRepartidor'
        _links:
          type: object
          description: hypermedia links de un repartidor
          readOnly: true
          properties:
            vehiculos: 
              $ref: '#/components/schemas/Link'
            delete:
              $ref: '#/components/schemas/Link'
      required: [id, nombre, apellido, CUIL, edad]
    EdadRepartidor:
      description: edad del repartidor
      type: integer
      example: 27
    _VehiculoBase:
      description: objeto base para construir vehículos de tipos particulares
      type: object
      discriminator:
        propertyName: tipoDeVehiculo
      properties:
        tipodeVehiculo:
          type: string
          description: tipo de vehículo
          example: VehiculoMoto
        id:
          type: integer
          description: identificador único del vehículo
          readOnly: true
          example: 3
        _links:
          type: object
          description: hypermedia links de un vehículo
          readOnly: true
          properties:
            repartidor: 
              $ref: '#/components/schemas/Link'
            delete:
              $ref: '#/components/schemas/Link'
      required: [id, tipodeVehiculo]
    VehiculoAuto:
      description: automóvil para repartos
      allOf:
      - $ref: '#/components/schemas/_VehiculoBase'
      - type: object
        properties:
          patente:
            type: string
            description: patente legal del vehículo
            example: ABC789
        required: [patente]
    VehiculoMoto:
      description: motocicleta para repartos
      allOf:
      - $ref: '#/components/schemas/_VehiculoBase'
      - $ref: '#/components/schemas/VehiculoAuto'
    VehiculoBici:
      description: bicicleta para repartos
      allOf:
        - $ref: '#/components/schemas/_VehiculoBase'
        - type: object
          properties:
            rodado:
              type: integer
              description: rodado de la bicicleta
              example: 29
          required: [rodado]
    Vehiculo:
      description: vehículo asociado a los repartidores
      oneOf:
        - $ref: '#/components/schemas/VehiculoAuto'
        - $ref: '#/components/schemas/VehiculoMoto'
        - $ref: '#/components/schemas/VehiculoBici'