openapi: 3.0.0
info:
  version: v0.0.0
  title: Parcel Delivery System API (Amanises)
  description: |
    API for managing parcel deliveries via automated locker systems.

    API domain: https://bytetype-cea685bb8e38.herokuapp.com
servers:
  - url: https://bytetype-cea685bb8e38.herokuapp.com/api
    description: server
tags:
  - name: Authentication
    description: User authentication operations
  - name: User
    description: Operations about user
  - name: Parcel
    description: Operations for parcels
  - name: Locker
    description: Operation for lockers
components:
  schemas:
    RoleType:
      type: string
      enum:
        - ROLE_GUEST
        - ROLE_USER
        - ROLE_DRIVER
      description: The roles assigned to the authenticated account.
      example:
        - ROLE_USER
        - ROLE_DRIVER
    ParcelStatus:
      type: string
      enum:
        - READY_FOR_PICKUP
        - PICKED_UP
        - DELIVERED
      description: >-
        ParcelStatus represents the current state of the parcel in the delivery
        process.
      example:
        - DELIVERED
    UserPayload:
      type: object
      properties:
        id:
          type: integer
          format: int64
          description: The user's unique identifier.
        username:
          type: string
          description: The username of the user.
        email:
          type: string
          format: email
          description: The email address of the user.
        phone:
          type: string
          description: The phone number of the user.
        address:
          type: string
          description: The address of the user.
      description: UserPayload includes user details as they appear in a parcel response.
      example:
        id: 1
        username: Caden Cicaro
        email: Cicaro@noreply.com
        phone: '9876543210'
        address: 47 Resonance Ridge, Cicadaville, Echo Valley, EV 90321
    ParcelPayload:
      type: object
      properties:
        sender:
          $ref: '#/components/schemas/UserPayload'
        recipient:
          $ref: '#/components/schemas/UserPayload'
        width:
          type: number
          format: double
          description: The width of the parcel.
        height:
          type: number
          format: double
          description: The height of the parcel.
        depth:
          type: number
          format: double
          description: The depth of the parcel.
        mass:
          type: number
          format: double
          description: The mass of the parcel.
      description: ParcelPayload includes parcel general details.
      example:
        sender:
          id: 1
          username: Caden Cicaro
          email: Cicaro@noreply.com
          phone: '9876543210'
          address: 47 Resonance Ridge, Cicadaville, Echo Valley, EV 90321
        recipient:
          id: 2
          username: Lara Skylarke
          email: Skylarke@noreply.com
          phone: '1234567890'
          address: 152 Harmony Heights, Larkspur Lane, Melodia, ME 41759
        width: 50
        height: 30
        depth: 20
        mass: 4.5
    CabinetPayload:
      type: object
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier of the cabinet.
        isLocked:
          type: boolean
          description: Indicates whether the cabinet is locked.
      example:
        id: 1
        isLocked: false
    LockerPayload:
      type: object
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier of the locker.
        location:
          type: string
          description: The location of the locker.
        cabinets:
          type: array
          items:
            $ref: '#/components/schemas/CabinetPayload'
      example:
        id: 1
        location: Central Station, Metropolis, MT
        cabinets:
          - id: 1
            isLocked: true
          - id: 2
            isLocked: false
    MessageResponse:
      type: object
      properties:
        message:
          type: string
          description: A message conveying the result of an operation.
          example: User registered successfully!
    LoginRequest:
      type: object
      required:
        - username
        - password
      properties:
        username:
          type: string
          description: The username of the account.
          example: Caden Cicaro
        password:
          type: string
          description: The password of the account.
          example: CadenPassword
    SignupRequest:
      type: object
      required:
        - username
        - password
        - address
      properties:
        username:
          type: string
          description: The username for the new account.
          example: Caden Cicaro
        email:
          type: string
          description: The email address of the new account.
          example: Cicaro@noreply.com
        password:
          type: string
          description: The secret password for the new account.
          example: CadenPassword
        address:
          type: string
          description: The Physical address of the account.
          example: 123 Main St, Anytown, AN 12345
        roles:
          type: array
          items:
            $ref: '#/components/schemas/RoleType'
    UserInfoResponse:
      type: object
      properties:
        username:
          type: string
          description: The username of the authenticated account.
          example: Caden Cicaro
        email:
          type: string
          description: The email address of the authenticated account.
          example: Cicaro@noreply.com
        phone:
          type: string
          description: The phone number of the authenticated account.
          example: '9876543210'
        address:
          type: string
          description: The address of the authenticated account.
          example: 47 Resonance Ridge, Cicadaville, Echo Valley, EV 90321
        roles:
          $ref: '#/components/schemas/RoleType'
    UserDetailResponse:
      allOf:
        - $ref: '#/components/schemas/UserPayload'
        - type: object
          properties:
            roles:
              type: array
              items:
                $ref: '#/components/schemas/RoleType'
            parcels:
              type: array
              items:
                $ref: '#/components/schemas/ParcelPayload'
    ParcelArriveRequest:
      type: object
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier of the parcel.
        readyForPickupAt:
          type: string
          format: date-time
          description: The time when the parcel is ready for pickup.
        cabinetId:
          type: integer
          format: int64
          description: The identifier of the cabinet where the parcel is stored.
    ParcelDeliveryRequest:
      allOf:
        - $ref: '#/components/schemas/ParcelPayload'
        - type: object
          properties:
            readyForPickupAt:
              type: string
              format: date-time
              description: Expected time for the parcel to be ready for pickup.
            expectedLockerId:
              type: array
              items:
                type: integer
                format: int64
              description: List of expected locker identifiers for the parcel.
    ParcelPickUpRequest:
      type: object
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier of the parcel.
        pickedUpAt:
          type: string
          format: date-time
          description: The exact time when the parcel was picked up.
        pickupCode:
          type: string
          description: The code required to pick up the parcel.
    ParcelArriveResponse:
      allOf:
        - $ref: '#/components/schemas/ParcelPayload'
        - type: object
          properties:
            id:
              type: integer
              format: int64
              description: The unique identifier of the parcel.
            status:
              $ref: '#/components/schemas/ParcelStatus'
            pickupCode:
              type: string
              description: The code required to pick up the parcel.
    ParcelDeliveryResponse:
      allOf:
        - $ref: '#/components/schemas/ParcelPayload'
        - type: object
          properties:
            id:
              type: integer
              format: int64
              description: The unique identifier of the parcel.
            status:
              $ref: '#/components/schemas/ParcelStatus'
            readyForPickupAt:
              type: string
              format: date-time
              description: The time when the parcel is ready for pickup.
            deliveryCode:
              type: string
              description: The delivery code for the parcel.
            expectedLocker:
              type: array
              items:
                $ref: '#/components/schemas/LockerPayload'
              description: The list of expected lockers for the parcel.
    ParcelPickUpResponse:
      allOf:
        - $ref: '#/components/schemas/ParcelPayload'
        - type: object
          properties:
            id:
              type: integer
              format: int64
              description: The unique identifier of the parcel.
            status:
              $ref: '#/components/schemas/ParcelStatus'
            pickedUpAt:
              type: string
              format: date-time
              description: The exact time when the parcel was picked up.
    LockerRequest:
      type: object
      properties:
        location:
          type: string
          description: The location of the locker.
        size:
          type: integer
          format: int32
          description: The size of the locker.
    LockerResponse:
      type: object
      properties:
        location:
          type: string
          description: The location of the locker.
        cabinets:
          type: array
          items:
            $ref: '#/components/schemas/CabinetPayload'
          description: The list of cabinets in the locker.
paths:
  /auth/signin:
    post:
      tags:
        - Authentication
      summary: Login a user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginRequest'
      responses:
        '200':
          description: Authentication successful
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserInfoResponse'
  /auth/signup:
    post:
      tags:
        - Authentication
      summary: Register a new user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignupRequest'
      responses:
        '200':
          description: Registration successful
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
  /auth/signout:
    post:
      tags:
        - Authentication
      summary: Logout user
      responses:
        '200':
          description: Sign out successful
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
  /auth/{id}:
    delete:
      tags:
        - Authentication
      summary: Remove user account
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: User account removed successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
  /user/{id}:
    get:
      tags:
        - User
      summary: Get user detail
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Get user detail successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserDetailResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
  /parcels/{id}:
    get:
      tags:
        - Parcel
      summary: Get a parcel by ID
      description: >-
        Retrieve detailed information about a parcel using its unique
        identifier.
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
            format: int64
          description: The unique ID of the parcel.
      responses:
        '200':
          description: Parcel retrieved successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParcelPayload'
              examples:
                parcel:
                  value:
                    id: 123
                    sender:
                      id: 101
                      username: john_doe
                      email: john@example.com
                      phone: '1234567890'
                      address: 123 Main St
                    recipient:
                      id: 102
                      username: jane_doe
                      email: jane@example.com
                      phone: '0987654321'
                      address: 456 Elm St
                    width: 30
                    height: 20
                    depth: 15
                    mass: 2.5
                    readyForPickupAt: '2023-11-01T09:00:00Z'
                    pickedUpAt: '2023-11-01T11:00:00Z'
                    status: shipped
                    pickupCode: PK123456
    delete:
      tags:
        - Parcel
      summary: Delete a parcel
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
            format: int64
          description: The ID of the parcel to delete.
      responses:
        '200':
          description: Parcel deleted successfully.
  /parcels/delivery:
    post:
      tags:
        - Parcel
      summary: Create and delivery a new parcel
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ParcelDeliveryRequest'
      responses:
        '200':
          description: Parcel created successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParcelDeliveryResponse'
        '400':
          description: Bad request (Invalid data or constraints violated).
  /parcels/arrive:
    post:
      tags:
        - Parcel
      summary: Arrive a parcel
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ParcelArriveRequest'
      responses:
        '200':
          description: Parcel created successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParcelArriveResponse'
        '400':
          description: Bad request (Invalid data or constraints violated).
  /parcels/pickup:
    post:
      tags:
        - Parcel
      summary: Pick up a parcel
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ParcelPickUpRequest'
      responses:
        '200':
          description: Parcel created successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParcelPickUpResponse'
        '400':
          description: Bad request (Invalid data or constraints violated).
  /lockers:
    get:
      tags:
        - Locker
      summary: Search a locker by location
      parameters:
        - in: path
          name: location
          required: true
          schema:
            type: string
          description: The location of the parcel.
      responses:
        '200':
          description: The locker details and cabinets.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LockerResponse'
        '400':
          description: Bad request (Invalid data or constraints violated).
    post:
      tags:
        - Locker
      summary: Create a locker with cabinets
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LockerRequest'
      responses:
        '200':
          description: The locker details and cabinets.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LockerResponse'
        '400':
          description: Bad request (Invalid data or constraints violated).
