swagger: "2.0"
info:
  description: "OWS Video."
  version: 1.0.1
  title: Video API Specification
host: "qa-ows-video.theorchard.io"
#host: "127.0.0.1:8081"
basePath: "/grass/video"

schemes:
#- "http"
 - "https"

consumes:
- "application/json"
produces:
- "application/json"

paths:
  /hello/:
    get:
      summary: "Check the health of the application."
      description: "Check the health of the application."
      operationId: "health"
      responses:
        500:
          $ref: '#/responses/InternalError'
        200:
          description: "OK"
          schema:
            properties:
              status:
                type: string
                default: "ok"


  /job/{job_id}:
    get:
      tags:
      - "Job"
      summary: "Get a job."
      description: "Get a job."
      operationId: "getJobById"
      parameters:
      - name: "job_id"
        in: "path"
        description: "Status values that need to be considered for filter"
        required: true
        type: "integer"
        default: "42"
      responses:
        500:
          description: "Invalid input"
        200:
          description: "OK"


  /jobs:
    get:
      tags:
      - "Job"
      summary: Search for jobs with specific field values.
      parameters:
      - name: "job_id"
        in: "query"
        description: "Filter by job_id"
        required: false
        type: "integer"
        default: 42
      - name: "job_parent_id"
        in: "query"
        description: "Filter by job_parent_id"
        required: false
        type: "integer"
        default: 41
      responses:
        200:
          description: Job info.
          schema:
            $ref: "#/definitions/GetJobsResponse"


  /job:
    post:
      tags:
      - "Job"
      summary: Create a job and add inputs, outputs, and statuses.
      parameters:
      - name: "data"
        in: "body"
        description: "Request payload"
        required: true
        schema:
          $ref: "#/definitions/Stub"
      responses:
        200:
          description: Job info.
          schema:
            $ref: "#/definitions/GetJobsResponse"


  /manage_job:
    post:
      tags:
      - "Job"
      summary: "Create a job and add inputs, outputs, and statuses."
      parameters:
      - name: "data"
        in: "body"
        description: "Request payload"
        schema:
          $ref: "#/definitions/Stub"
      responses:
        200:
          description: "Response."
          schema:
            $ref: "#/definitions/Stub"


  /new_assets/{dashboard_item_id}:
      get:
        tags:
        - "Assets"
        summary: "Get new assets from video dashboard item table."
        description: "Get new assets from video dashboard item table."
        operationId: "get_new_assets"
        parameters:
        - name: "dashboard_item_id"
          in: "path"
          description: "Status values that need to be considered for filter"
          required: true
          type: "integer"
          default: "42"
        responses:
          500:
            description: "Invalid input"
          200:
            description: "OK"
            schema:
              type: object
              properties:
                items:
                  type: array
                  items:
                    type: object
                    properties:
                      asset_id:
                        type: integer
                      dashboard_item_id:
                        type: integer
                      product_id:
                        type: integer
                pagination:
                  $ref: "#/definitions/Pagination"


  /max_dashboard_item_id:
    get:
      tags:
      - "Dashboard"
      summary: "Get most recent id from video dashboard item table."
      description: "Get most recent id from video dashboard item table."
      operationId: "get_max_dashboard_item_id"
      responses:
        200:
          description: "OK"
          schema:
            type: object
            properties:
              max_dashboard_item_id:
                type: integer


  /stream/product/{product_id}/hls:
    get:
      tags:
      - "Stream"
      summary: "Get a HLS URL for a product."
      description: "Get a HLS URL for a product."
      operationId: "get_hls_streaming_url"
      parameters:
      - in: header
        name: Orchard-User-Id
        type: "string"
        description: "The orchard user ID"
      - in: header
        name: referer
        type: "string"
        description: "The request's referrer."
      - in: path
        name: product_id
        type: integer
        description: "ID of the product"
        required: true
      responses:
        200:
          description: "OK"
          schema:
            type: object
            properties:
              url:
                type: "string"
        404:
          $ref: '#/responses/NotFound'


  /create_product:
    post:
      tags:
      - "Product"
      summary: "Create a product."
      description: "Create a product."
      operationId: "create_product"
      parameters:
      - in: header
        name: "Grass-Account-Type"
        type: "string"
        description: "Grass-Account-Type"
      - in: header
        name: "Grass-Account-Id"
        type: "string"
        description: "Grass-Account-Id"
      - in: body
        name: data
        description: "ID of the product"
        required: true
        schema:
          properties:
            project_id:
              type: integer
              default: 3323569
      responses:
        404:
          $ref: '#/responses/NotFound'
        200:
          description: "OK"
          schema:
            $ref: '#/definitions/ProductVideo'


  /product/{product_id}:
    delete:
      tags:
      - "Product"
      summary: "Delete a product."
      description: "Delete a product."
      operationId: "delete_product"
      parameters:
      - in: path
        name: "product_id"
        type: "integer"
        description: "Product Id"
        required: true
      - in: header
        name: "Grass-Account-Type"
        type: "string"
        description: "Grass-Account-Type"
      - in: header
        name: "Grass-Account-Id"
        type: "string"
        description: "Grass-Account-Id"
      responses:
        404:
          $ref: '#/responses/NotFound'
        500:
          $ref: '#/responses/InternalError'
        200:
          description: "OK"


  /product/disassociate-tracks:
    post:
      tags:
      - "Product"
      summary: "Disassociate tracks from video products."
      description: "Null associated_track_id on video products referencing the\
        \ given track tuids. Plain UPDATE with no metadata or re-delivery side\
        \ effects."
      operationId: "disassociate_tracks"
      parameters:
      - in: body
        name: data
        required: true
        schema:
          type: object
          additionalProperties: false
          required:
          - track_ids
          properties:
            track_ids:
              type: array
              minItems: 1
              uniqueItems: true
              items:
                type: integer
                minimum: 1
      responses:
        400:
          $ref: '#/responses/BadRequest'
        500:
          $ref: '#/responses/InternalError'
        200:
          description: "OK"


  /metadata/{product_id}/track:
    post:
      tags:
      - "Metadata"
      summary: "Create product metadata."
      description: "Create product metadata."
      operationId: "create_track_metadata"
      parameters:
      - in: path
        name: product_id
        required: true
        type: "integer"
      - in: body
        name: data
        description: "ID of the product"
        required: true
        schema:
          $ref: '#/definitions/TrackVideoMetadata'
      responses:
        404:
          $ref: '#/responses/NotFound'
        500:
          $ref: '#/responses/InternalError'
        201:
          description: "Created"
          schema:
            $ref: '#/definitions/TrackVideoMetadata'


  /metadata/{product_id}:
    get:
      tags:
      - "Metadata"
      summary: "Load metadata."
      description: "Load metadata."
      operationId: "load_metadata"
      parameters:
      - in: path
        name: product_id
        required: true
        type: "integer"
      - in: header
        name: "Grass-Account-Type"
        type: "string"
        description: "Grass-Account-Type"
      - in: header
        name: "Grass-Account-Id"
        type: "string"
        description: "Grass-Account-Id"
      responses:
        200:
          description: "OK"
          schema:
            $ref: '#/definitions/ProductVideo'
        404:
          $ref: '#/responses/NotFound'
        500:
          $ref: '#/responses/InternalError'

    post:
      tags:
      - "Metadata"
      summary: "Save metadata."
      description: "Save metadata."
      operationId: "save_metadata"
      parameters:
      - in: path
        name: product_id
        required: true
        type: "integer"
      - in: header
        name: "Grass-Account-Type"
        type: "string"
        description: "Grass-Account-Type"
      - in: header
        name: "Grass-Account-Id"
        type: "string"
        description: "Grass-Account-Id"
      - in: header
        name: "Orchard-User-Id"
        type: "string"
        description: "Orchard-User-Id"
      - in: body
        name: data
        description: "product video metadata"
        required: true
        schema:
          $ref: '#/definitions/ProductVideo'
      responses:
        200:
          description: "OK"
          schema:
            $ref: '#/definitions/ProductVideo'
        400:
          $ref: '#/responses/BadRequest'
        404:
          $ref: '#/responses/NotFound'
        500:
          $ref: '#/responses/InternalError'


  /metadata/bulk-ingest:
    post:
      tags:
      - "Metadata"
      summary: "Bulk ingest metadata."
      description: "Bulk ingest metadata."
      operationId: "bulk_ingest_metadata"
      parameters:
      - in: body
        name: data
        description: "array of product video metadata"
        required: true
        schema:
          type: array
          items:
            $ref: '#/definitions/Stub'
      responses:
        200:
          description: "OK"
          schema:
            type: object
            properties:
              successes:
                type: array
                items:
                  $ref: '#/definitions/Stub'
              errors:
                type: array
                items:
                  $ref: '#/definitions/Stub'


  /product/{product_id}/submit:
    post:
      tags:
      - "Product"
      summary: "User submitting their product for review."
      description: "User submitting their product for review."
      operationId: "submit"
      parameters:
      - in: path
        name: product_id
        required: true
        type: "integer"
      - in: header
        name: "Grass-Account-Type"
        type: "string"
        description: "Grass-Account-Type"
      - in: header
        name: "Grass-Account-Id"
        type: "string"
        description: "Grass-Account-Id"
      responses:
        200:
          description: "OK"
          schema:
            $ref: '#/definitions/Stub'
        400:
          $ref: '#/responses/BadRequest'


  /product/{product_id}/approval:
    get:
      tags:
      - "Product"
      summary: "OA User approval."
      description: "OA User approval."
      operationId: "get_approvals"
      parameters:
      - in: path
        name: product_id
        required: true
        type: "integer"
      responses:
        200:
          description: "OK"
          schema:
            $ref: '#/definitions/ApprovalResponse'
        400:
          $ref: '#/responses/BadRequest'
    post:
      tags:
      - "Product"
      summary: "OA User approval."
      description: "OA User approval."
      operationId: "change_approval"
      parameters:
      - in: path
        name: product_id
        required: true
        type: "integer"
      - in: header
        name: "Orchard-User-Id"
        type: "string"
        description: "Orchard-User-Id"
        default: 'oa:user'
      - in: body
        name: data
        required: true
        schema:
          $ref: '#/definitions/ApprovalRequest'
      responses:
        200:
          description: "OK"
          schema:
            $ref: '#/definitions/ApprovalResponse'
        201:
          description: "Created"
          schema:
            $ref: '#/definitions/ApprovalResponse'
        400:
          $ref: '#/responses/BadRequest'


  /product/{product_id}/get_available_channels:
    get:
      tags:
      - "Product"
      summary: "Get available channels."
      description: "Get available channels."
      operationId: "get_available_channels"
      parameters:
      - in: path
        name: product_id
        required: true
        type: "integer"
      - in: header
        name: "Grass-Account-Type"
        type: "string"
        description: "Grass-Account-Type"
      - in: header
        name: "Grass-Account-Id"
        type: "string"
        description: "Grass-Account-Id"
      responses:
        200:
          description: "OK"
          schema:
            type: array
            items:
              $ref: '#/definitions/ArtistDeliverySettings'
        500:
          $ref: '#/responses/InternalError'


  /migrate_artist/{product_id}:
    put:
      tags:
      - "Product"
      summary: "Update the primary_artist of a product_video."
      description: "Update the primary_artist of a product_video."
      operationId: "migrate_artist"
      parameters:
      - in: path
        name: product_id
        required: true
        type: "integer"
        description: "ID of the product"
      - in: header
        name: "Grass-Account-Type"
        type: "string"
        description: "Grass-Account-Type"
      - in: header
        name: "Grass-Account-Id"
        type: "string"
        description: "Grass-Account-Id"
      - name: "data"
        in: "body"
        description: "Request payload for migrate artist"
        required: true
        schema:
          $ref: "#/definitions/MigrateArtist"
      responses:
        200:
          description: "OK"
          schema:
            $ref: '#/definitions/MigrateArtistResponse'
          examples:
            application/json:
              {
                "id": 34077,
                "release_id": 2763547,
                "latest_pipeline_run_id": 491858,
                "type_of_video": "Promo",
                "language_of_video_title": "ENG",
                "video_title": "afina vid",
                "version": null,
                "product_code": "dfgvhjkl3",
                "description": null,
                "upc": null,
                "isrc": null,
                "imprint": "1406imprint (release)",
                "language_of_video_content": "ENG",
                "lyrics": null,
                "c_line_year": 1990,
                "c_line_copyright_holder": "my label",
                "p_line_year": 1990,
                "p_line_copyright_holder": "my label",
                "new_release": true,
                "original_release_date": null,
                "release_date": "2020-01-18",
                "special_instructions": null,
                "deliver_to_all": true,
                "parental_advisory": "No",
                "genre_id": 17,
                "subgenre_id": 952,
                "keywords": null,
                "contributors": null,
                "primary_artist_id": 856157,
                "is_valid": true,
                "preview_start_time": 0,
                "thumbnail_path": "491858/2763547.0000014.jpg",
                "thumbnail_at_milliseconds": 14000,
                "custom_thumbnail_path": null,
                "prores_path": null,
                "h264_path": null,
                "channel_selection": "I don't see the channel I want",
                "not_for_distribution": "N",
                "submitted_at": null,
                "ingest_filename": null,
                "associated_track_id": null,
                "associated_track": null
              }
        404:
          $ref: '#/responses/BadRequest'
        500:
          $ref: '#/responses/InternalError'


  /project/{project_id}/get_available_channels:
    get:
      tags:
      - "Project"
      summary: "Get available channels for project."
      description: "Get available channels for project."
      operationId: "get_project_available_channels"
      parameters:
      - in: path
        name: project_id
        required: true
        type: "integer"
      - in: header
        name: Orchard-User-Id
        type: "string"
        description: "The orchard user ID"
      responses:
        200:
          description: "OK"
          schema:
            type: array
            items:
              $ref: '#/definitions/ArtistDeliverySettings'
        500:
          $ref: '#/responses/InternalError'

  /workflow/{workflow_job_type}:
    post:
      tags:
      - "Workflow"
      summary: "Create skeleton of the jobs to be run in processing pipeline."
      description:
        "Create skeleton of the jobs to be run in processing pipeline.
        Note: a workflow is a high level definition of a set of
        video pipeline jobs to be used passed to the AWS State Machine
        so that the daemon has all the correct ids and job types to report
        back to ows-video about."
      operationId: "setup_workflow"
      parameters:
      - in: path
        name: workflow_job_type
        required: true
        type: "string"
        enum: [
                'workflow_ingest_from_browser',
                'workflow_ingest_from_google_drive',
                'workflow_ingest_from_dropbox',
                'workflow_ingest_from_s3',
                'workflow_approval'
              ]
      - in: body
        name: data
        required: true
        schema:
          $ref: '#/definitions/Stub'
      responses:
        200:
          description: "OK"
          schema:
            type: array
            items:
              $ref: '#/definitions/Job'
        500:
          $ref: '#/responses/InternalError'


  /thumbnails/job/{job_id}:
    get:
      tags:
      - "Job"
      summary: "Get the list of available thumbnails for a job."
      description: "Get the list of available thumbnails for a job."
      operationId: "get_available_thumbnails"
      parameters:
      - in: path
        name: job_id
        required: true
        type: integer
      responses:
        200:
          description: "OK"
          schema:
            type: object
            properties:
              items:
                type: array
                items:
                  type: string
                  description: 'url'
        500:
          $ref: '#/responses/InternalError'


  /thumbnails/product/{product_id}:
    get:
      tags:
      - "Product"
      summary: "Get the thumbnail associated with a product"
      description: "Get the thumbnail associated with a product"
      operationId: "get_product_thumbnail"
      parameters:
      - in: path
        name: product_id
        required: true
        type: integer
      - in: query
        name: image_size
        required: false
        type: string
        default: 'original-size'
      - in: query
        name: expire_at
        required: false
        type: integer
        description: "Timestamp in seconds when the url becomes invalid."
      responses:
        200:
          description: "OK"
          schema:
            type: object
            properties:
              url:
                type: string
        404:
          $ref: '#/responses/NotFound'
        500:
          $ref: '#/responses/InternalError'


  /thumbnails/upload-token:
    post:
      tags:
      - "Thumbnails"
      summary: "Generate a S3 token to upload a custom thumbnail."
      description: "Generate a S3 token to upload a custom thumbnail."
      operationId: "generate_upload_token_for_custom_thumbnail"
      parameters:
      - in: body
        name: data
        required: true
        schema:
          type: object
          properties:
            workflow_job_id:
              type: integer
            filename:
              type: string
      responses:
        200:
          description: "OK"
          schema:
            $ref: '#/definitions/Stub'
        404:
          $ref: '#/responses/NotFound'
        500:
          $ref: '#/responses/InternalError'


  /delivery/{upc}/status:
    get:
      tags:
      - "Thumbnails"
      summary: "Get status of ripper ripping asset."
      description: "Get status of ripper ripping asset."
      operationId: "get_asset_delivery_status"
      parameters:
      - in: path
        name: upc
        type: string
        required: true
      - in: query
        name: asset_type
        type: string
        required: false
      responses:
        200:
          description: "OK"
        404:
          $ref: '#/responses/NotFound'


  /workflow/{workflow_job_id}/transfer/{filename}/progress:
    get:
      tags:
      - "Workflow"
      summary: "Get cloud transfer progress."
      description: "Get cloud transfer progress."
      operationId: "get_cloud_transfer_progress"
      parameters:
      - in: path
        name: workflow_job_id
        type: integer
        required: true
      - in: path
        name: filename
        type: string
        required: true
      - in: query
        name: asset_type
        type: string
        required: false
      responses:
        200:
          description: "Can't find out the type now, guess it's just int"
          schema:
            $ref: "#/definitions/Stub"
        404:
          $ref: '#/responses/NotFound'
        500:
          $ref: '#/responses/InternalError'


  /ingest:
    post:
      tags:
      - "Workflow"
      summary: "Generate a S3 token to upload a custom thumbnail."
      description: "Generate a S3 token to upload a custom thumbnail."
      operationId: "ingest"
      parameters:
      - name: "data"
        in: "body"
        description: "Request payload - needs clarification"
        required: true
        schema:
          $ref: "#/definitions/Stub"
      responses:
        200:
          description: "OK"
          schema:
            $ref: '#/definitions/Stub'
        500:
          $ref: '#/responses/InternalError'


  /video-asset:
    post:
      tags:
      - "Video Asset"
      summary: "Upsert a video asset."
      description: "Create or update a video asset."
      parameters:
      - name: "data"
        in: "body"
        schema:
          $ref: "#/definitions/VideoAsset"
      responses:
        200:
          description: "OK"
          schema:
            $ref: '#/definitions/VideoAsset'
        500:
          $ref: '#/responses/InternalError'


# ======================
# Responses
# ======================

responses:

  NotFound:
    description: The specified resource was not found
    schema:
      $ref: '#/definitions/BaseError'

  InternalError:
    description: Internal Error
    schema:
      $ref: '#/definitions/BaseError'

  BadRequest:
    description: Bad Request
    schema:
      $ref: '#/definitions/BaseError'


# ======================
# Definitions
# ======================

definitions:

  Stub:
    type: object

  ApprovalResponse:
    type: object
    properties:
      id:
        type: integer
      release_id:
        type: integer
      content_approved:
        type: boolean
      release_approved:
        type: boolean
      rejection_reason:
        type: string

  ApprovalRequest:
    type: object
    properties:
      approval_type:
        type: string
        enum: ["final", "release", "content"]
        default: release
      value:
        type:
          boolean
        description: "Boolean or String"

  ArtistDeliverySettings:
    type: object
    properties:
      id:
        type: integer
      artist_id:
        type: integer
      channel_id:
        type: string
      channel_name:
        type: string
      vevo_controlled:
        type: string
        enum: ['No', 'Yes']

  BaseError:
    type: object
    properties:
      code:
        type: "string"
      message:
        type: "string"

  Track:
    type: object
    properties:
      track_id:
        type: "integer"
      duration_minutes:
        type: "integer"
      duration_seconds:
        type: "integer"
      closed_caption_exists:
        type: "integer"
        default: null
      closed_caption_reason_id:
        type: "integer"
        default: null

  TrackVideo:
    type: object
    properties:
      fps:
        type: "string"
        enum: ['30', '25', '24', '15', '12']
      resolution:
        type: "string"
        enum: ['SD', '720HD', '1080HD', '4k']
      aspect_ratio:
        type: "string"
        enum: ['4:3', '16:9', '8:5', '5:3', '40:23', '20:11', '40:21', '4:2', '40:19',
          '20:9', '3:2', '40:17', '5:2', '8:3', '20:7', '40:29', '10:7', '40:27',
          '20:13', '1.85:1']
      color:
        type: "string"
        enum: ['black_and_white', 'color']
      channel:
        type: "string"

  TrackVideoMetadata:
    type: object
    properties:
      duration_minutes:
        type: "integer"
      duration_seconds:
        type: "integer"
      closed_caption_exists:
        type: "integer"
        default: null
      closed_caption_reason_id:
        type: "integer"
        default: null
      fps:
        type: "string"
        enum: ['30', '25', '24', '15', '12']
      resolution:
        type: "string"
        enum: ['SD', '720HD', '1080HD', '4k']
      aspect_ratio:
        type: "string"
        enum: ['4:3', '16:9', '8:5', '5:3', '40:23', '20:11', '40:21', '4:2', '40:19',
          '20:9', '3:2', '40:17', '5:2', '8:3', '20:7', '40:29', '10:7', '40:27',
          '20:13', '1.85:1']
      color:
        type: "string"
        enum: ['black_and_white', 'color']
      channel:
        type: "string"

  ProductVideo:
    type: object
    description: "Product Video Metadata"
    properties:
      id:
        type: integer
      release_id:
        type: integer
      latest_pipeline_run_id:
        type: integer
      type_of_video:
        type: string
        enum: ['Official Music Video',
          'Lyric Music Video',
          'Pseudo Video',
          'Behind the Scenes',
          'Promo',
          'Live Performance',
          'Other']
      language_of_video_title:
        type: string
      video_title:
        type: string
      version:
        type: string
      product_code:
        type: string
      description:
        type: string
      upc:
        type: integer
      isrc:
        type: string
      imprint:
        type: string
      language_of_video_content:
        type: string
      lyrics:
        type: string
      c_line_year:
        type: integer
      c_line_copyright_holder:
        type: string
      p_line_year:
        type: integer
      p_line_copyright_holder:
        type: string
      new_release:
        type: boolean
      original_release_date:
        type: "string"
        format: "date"
      release_date:
        type: "string"
        format: "date"
      special_instructions:
        type: "string"
      deliver_to_all:
        type: boolean
      parental_advisory:
        type: string
        enum: ['No', 'Yes', 'Clean Version']
      genre_id:
        type: integer
      subgenre_id:
        type: integer
      keywords:
        type: "string"
      contributors:
        type: array
        items:
          $ref: '#/definitions/Contributor'
      primary_artist_id:
        type: integer
      is_valid:
        type: boolean
      preview_start_time:
        type: integer
      thumbnail_path:
        type: "string"
      thumbnail_at_milliseconds:
        type: integer
      custom_thumbnail_path:
        type: "string"
      channel_selection:
        type: "string"
      not_for_distribution:
        type: string
        enum: [
          'N',
          'AccountingDummy',
          'EditoriallySuspectContent',
          'NotforFurtherDistribution',
          'TVSeasonAccountingDummy',
          'LabelRCRevenueDummy',
          'iTunesRingtone',
          'CatalogDuplicate',
          'YouTubeRemap',
          'PhysicalProduct',
          'IncompleteAssets',
          'SwitchboardDummy',
          'SMEAnalyticsDummy',
          'MissingAssets',
          'AWALNotOurDistribution'
        ]
      submitted_at:
        type: "string"
        format: "date-time"
      ingest_filename:
        type: "string"
      associated_track_id:
        type: integer
      associated_track:
        $ref: '#/definitions/AssociatedTrack'
      errors:
        type: array
        items: {}

  Contributor:
    properties:
        role:
          type: "string"
        name:
          type: "string"

  Job:
    properties:
      id:
        type: "integer"
      parent_id:
        type: "integer"
      status:
        type: "string"
        enum: [CANCELLED]
      type:
        type: "string"
        enum: [transfer_from_browser_to_s3]
      context:
        type: object
        properties:
          schema:
            $ref: "#/definitions/Context"

  GetJobsResponse:
    properties:
      items:
        type: array
        items:
          $ref: "#/definitions/Job"
      pagination:
        type: object
        properties:
          schema:
            $ref: "#/definitions/Pagination"
      extra:
        type: integer

  Context:
    properties:
      correlation_id:
        type: "string"
      datetime:
        type: "string"
        format: "date-time"
      id:
        type: "integer"
      user_id:
        type: "string"
        example: 'alw:17411'
      vendor_id:
        type: "integer"
        example: 16156

  Pagination:
    properties:
      limit:
        type: integer
        default: 1000
      offset:
        type: string
        example: '0'
        description: "Integer as string :("
      total_records:
        type: integer
        example: 1
      type:
        type: "string"
        enum: ["standard"]

  AssociatedTrack:
    properties:
      tuid:
        type: integer
      isrc:
        type: string
      track_name:
        type: string

  VideoAsset:
    type: object
    properties:
      product_id:
        type: "integer"
      asset_type:
        type: "string"
      asset_path:
        type: "string"

  MigrateArtist:
    properties:
        artist_id:
          type: integer

  MigrateArtistResponse:
        type: object
        properties:
          id:
            type: integer
          release_id:
            type: integer
          latest_pipeline_run_id:
            type: integer
          type_of_video:
            type: string
          language_of_video_title:
            type: string
          video_title:
            type: string
          version:
            type: string
          product_code:
            type: string
          description:
            type: string
          upc:
            type: integer
          isrc:
            type: string
          imprint:
            type: string
          language_of_video_content:
            type: string
          lyrics:
            type: string
          c_line_year:
            type: integer
          c_line_copyright_holder:
            type: string
          p_line_year:
            type: integer
          p_line_copyright_holder:
            type: string
          new_release:
            type: boolean
          original_release_date:
            type: string
          release_date:
            type: string
          special_instructions:
            type: string
          deliver_to_all:
            type: boolean
          parental_advisory:
            type: string
          genre_id:
            type: integer
          subgenre_id:
            type: integer
          keywords:
            type: string
          contributors:
            type: string
          primary_artist_id:
            type: integer
          is_valid:
            type: boolean
          preview_start_time:
            type: integer
          thumbnail_path:
            type: string
          thumbnail_at_milliseconds:
            type: integer
          custom_thumbnail_path:
            type: string
          prores_path:
            type: string
          h264_path:
            type: string
          channel_selection:
            type: string
          not_for_distribution:
            type: string
          submitted_at:
            type: string
          ingest_filename:
            type: string
          associated_track_id:
            type: integer
          associated_track:
            type: object
            properties:
              tuid:
                type: integer
              isrc:
                type: string
              track_name:
                type: string


#================
# JobInputs
#================
  CalculateAudioStatsJobInput:
    additionalProperties: false
    properties:
      input_video_s3_bucket:
        type: "string"
      input_video_s3_key:
        type: "string"
    type: object


  JobType:
    properties:
# ================
# Job Types Begin
# ================
      calculate_audio_stats:
        additionalProperties: false
        properties:
          input_video_s3_bucket:
            type: "string"
          input_video_s3_key:
            type: "string"
        type: object

      convert_default_thumbnail_to_tiff:
        additionalProperties: false
        properties:
          thumbnail_s3_key:
            type: "string"
          workflow_job_id:
            type: integer
        type: object

      create_mezzanines:
        additionalProperties: false
        properties:
          audio_stream_duration_seconds:
            type: number
          audio_volume_adjustment_db:
            type: number
          input_clip_end_timecode:
            type: "string"
          input_clip_start_timecode:
            type: "string"
          input_video_s3_bucket:
            type: "string"
          input_video_s3_key:
            type: "string"
          product_id:
            type: "integer"
          video_inner_height_pixels:
            type: integer
          video_inner_top_left_corner_x_pixels:
            type: integer
          video_inner_top_left_corner_y_pixels:
            type: integer
          video_inner_width_pixels:
            type: integer
          video_output_inner_height_pixels:
            type: integer
          video_output_outer_height_pixels:
            type: integer
          video_output_inner_width_pixels:
            type: integer
          video_output_outer_width_pixels:
            type: integer
          video_stream_duration_seconds:
            type: number
          video_stream_frame_rate_frames_per_second:
            type: number
          workflow_job_id:
            type: integer
        type: object

      create_streamable_preview_and_thumbnails:
        additionalProperties: false
        properties:
          audio_stream_duration_seconds:
            type: number
          audio_volume_adjustment_db:
            type: number
          input_clip_end_timecode:
            type: "string"
          input_clip_start_timecode:
            type: "string"
          input_video_s3_bucket:
            type: "string"
          input_video_s3_key:
            type: "string"
          product_id:
            type: "integer"
          video_inner_height_pixels:
            type: integer
          video_inner_top_left_corner_x_pixels:
            type: integer
          video_inner_top_left_corner_y_pixels:
            type: integer
          video_inner_width_pixels:
            type: integer
          video_output_inner_height_pixels:
            type: integer
          video_output_outer_height_pixels:
            type: integer
          video_output_inner_width_pixels:
            type: integer
          video_output_outer_width_pixels:
            type: integer
          video_stream_duration_seconds:
            type: number
          video_stream_frame_rate_frames_per_second:
            type: number
          workflow_job_id:
            type: integer
        type:
          object

      detect_black_intervals_at_beginning_and_end_of_video:
        additionalProperties: false
        properties:
          input_video_s3_bucket:
            type: "string"
          input_video_s3_key:
            type: "string"
          video_stream_duration_seconds:
            type: number
          video_stream_frame_rate_frames_per_second:
            type: number
        type:
          object

      detect_max_volume:
        additionalProperties: false
        properties:
          input_video_s3_bucket:
            type: "string"
          input_video_s3_key:
            type: "string"
        type:
          object

      detect_silent_intervals_at_beginning_and_end_of_audio:
        additionalProperties: false
        properties:
          audio_stream_duration_seconds:
            type: number
          input_video_s3_bucket:
            type: "string"
          input_video_s3_key:
            type: "string"
          video_stream_frame_rate_frames_per_second:
            type: number
        type:
          object

      detect_video_location_and_dimensions_within_black_border:
        additionalProperties: false
        properties:
          input_video_s3_bucket:
            type: "string"
          input_video_s3_key:
            type: "string"
        type: object

      extract_metadata:
        additionalProperties: false
        properties:
          input_video_s3_bucket:
            type: "string"
          input_video_s3_key:
            type: "string"
        type: object

      extract_prores_mezzanine_metadata:
        additionalProperties: false
        properties:
          product_id:
            type: integer
          prores_mezzanine_output_s3_key:
            type: "string"
        type: object

      get_create_mezzanines_inputs:
        additionalProperties: false
        properties:
          workflow_ingest_job_id:
            type: integer
        type: object

      get_product_metadata:
        additionalProperties: false
        properties:
          product_id:
            type: integer
        type: object

      transfer_from_browser_to_s3:
        additionalProperties: false
        properties:
          aws_access_key_id:
            type: "string"
          aws_secret_access_key:
            type: "string"
          filename:
            type: "string"
          filesize:
            type: number
          input_video_s3_bucket:
            type: "string"
          input_video_s3_key:
            type: "string"
          s3_token_expiration:
            type: "string"
          token:
            type: "string"
        type: object

      transfer_from_dropbox_to_s3:
        additionalProperties: false
        properties:
          dropbox_files:
            items:
              properties: {}
              type: object
            type: array
          transfer_from_dropbox_to_s3_job_id:
            type: integer
          workflow_job_id:
            type: integer
        type: object

      transfer_from_google_drive_to_s3:
        additionalProperties: false
        properties:
          google_drive_authorization:
            properties: {}
            type: object
          google_drive_files:
            items:
              properties: {}
              type: object
            type: array
          transfer_from_google_drive_to_s3_job_id:
            type: integer
          workflow_job_id:
            type: integer
        type: object

      transfer_from_s3_to_s3:
        additionalProperties: true
        properties:
          input_video_s3_bucket:
            type: "string"
          input_video_s3_key:
            type: "string"
          workflow_job_id:
            type: integer
        type:
          object

      transfer_h264_from_s3_to_ripper:
        additionalProperties: false
        properties:
          h264_mezzanine_output_s3_key:
            type: "string"
          prores_mezzanine_metadata:
            type: "string"
          upc:
            type: integer
        type: object

      transfer_prores_from_s3_to_ripper:
        additionalProperties: false
        properties:
          prores_mezzanine_output_s3_key:
            type: "string"
          upc:
            type: integer
        type: object

      transfer_tiff_thumbnail_from_s3_to_ripper:
        additionalProperties: false
        properties:
          tiff_thumbnail_s3_key:
            type: "string"
          upc:
            type: integer
        type: object

      validate_analysis:
        additionalProperties: false
        properties:
          black_interval_at_beginning_ends_at_seconds:
            type: number
          black_interval_at_end_begins_at_seconds:
            type: number
          left_audio_channel_rms_volume_decibels:
            type: number
          max_volume_decibels:
            type: number
          right_audio_channel_rms_volume_decibels:
            type: number
          silent_interval_at_beginning_ends_at_seconds:
            type: number
          silent_interval_at_end_begins_at_seconds:
            type: number
          video_inner_height_pixels:
            type: integer
          video_inner_width_pixels:
            type: integer
          video_stream_frame_rate_frames_per_second:
            type: number
          video_stream_pixel_aspect_ratio:
            type: number
        type: object

      validate_metadata:
        additionalProperties: false
        properties:
          audio_stream_bit_rate_bits_per_second:
            type: number
          audio_stream_channel_count:
            type: "integer"
          audio_stream_channel_layout:
            type: "string"
          audio_stream_codec:
            type: "string"
          audio_stream_codec_profile:
            type: "string"
          audio_stream_duration_seconds:
            type: number
          audio_stream_sample_rate_samples_per_second:
            type: number
          container_format:
            type: "string"
          container_format_profile:
            type: "string"
          num_audio_streams:
            type: integer
          num_video_streams:
            type: integer
          video_stream_bit_rate_bits_per_second:
            type: number
          video_stream_codec:
            type: "string"
          video_stream_codec_profile:
            type: "string"
          video_stream_duration_seconds:
            type: number
          video_stream_frame_rate_frames_per_second:
            type: number
          video_stream_height_pixels:
            type: number
          video_stream_pixel_aspect_ratio:
            type: number
          video_stream_width_pixels:
            type: number
        type: object

      workflow_approval:
        additionalProperties: false
        properties:
          should_transfer_prores_to_ripper:
            type: boolean
          workflow_ingest_job_id:
            type: integer
          workflow_job_id:
            type: integer
          workflow_state_machine_execution_arn:
            type: "string"
        type: object

      workflow_ingest_from_browser:
        additionalProperties: false
        properties:
          workflow_job_id:
            type: integer
          workflow_state_machine_execution_arn:
            type: "string"
        type:
          object

      workflow_ingest_from_dropbox:
        additionalProperties: false
        properties:
          dropbox_files:
            items:
              properties: {}
              type: object
            type: array
          workflow_job_id:
            type: integer
          workflow_state_machine_execution_arn:
            type: "string"
        type: object

      workflow_ingest_from_google_drive:
        additionalProperties: false
        properties:
          google_drive_authorization:
            properties: {}
            type: object
          google_drive_files:
            items:
              properties: {}
              type: object
            type: array
          workflow_job_id:
            type: integer
          workflow_state_machine_execution_arn:
            type: "string"
        type:
          object

      workflow_ingest_from_s3:
        additionalProperties: false
        properties:
          workflow_job_id:
            type: integer
          workflow_state_machine_execution_arn:
            type: "string"
        type:
          object
