openapi: 3.0.1 servers: - url: http://localhost:4550/ info: description: Modernised DARTS (Digital Audio Recording and Transcription Service). version: ${version} title: Modernised DARTS ######################################################################################################################## # PATH DEFINITIONS ######################################################################################################################## paths: /audio/hearings/{hearing_id}/audios: get: tags: - Audio summary: Media metadata for provided hearing operationId: getAudioMetadata description: Media metadata for provided hearing parameters: - in: path name: hearing_id schema: type: integer required: true responses: '200': description: OK content: application/json: schema: type: array items: $ref: '#/components/schemas/AudioMetadata' examples: media-found: summary: Media metadata exists for the given hearing id value: - id: 1 media_start_timestamp: '2023-07-31T14:32:24.620Z' media_end_timestamp: '2023-07-31T14:32:24.620Z' is_archived: true is_available: true media-not-found: summary: No media metadata exists for the given hearing id value: [ ] '422': description: Business Validation Error content: application/json+problem: schema: $ref: './problem.yaml' '400': description: Bad Request Error content: application/json+problem: schema: $ref: './problem.yaml' example: type: "AUTHORISATION_102" title: "Failed to check authorisation for the hearing" status: 400 '401': description: Unauthorised Error content: application/json+problem: schema: $ref: './problem.yaml' example: type: "AUTHORISATION_100" title: "User is not authorised for the associated courthouse" status: 401 '404': description: Not Found Error content: application/json+problem: schema: $ref: './problem.yaml' example: type: "HEARING_100" title: "The requested hearing cannot be found" status: 404 /audio/preview/{media_id}: get: tags: - Audio summary: Preview audio operationId: preview description: Preview audio. Use text/event-stream accept type to use send server events. parameters: - in: path name: media_id schema: type: integer format: int64 required: true description: "Internal identifier for media" example: 1 - in: header name: range schema: type: string description: "Range header, required for streaming audio." responses: '200': description: OK content: audio/mpeg: schema: type: string format: byte '422': description: Business Validation Error content: application/json+problem: schema: $ref: './problem.yaml' '400': description: Bad Request Error content: application/json+problem: schema: $ref: './problem.yaml' example: type: "AUTHORISATION_104" title: "Failed to check authorisation for the media" status: 400 '401': description: Unauthorised Error content: application/json+problem: schema: $ref: './problem.yaml' example: type: "AUTHORISATION_100" title: "User is not authorised for the associated courthouse" status: 401 '404': description: Not Found Error content: application/json+problem: schema: $ref: './problem.yaml' example: type: "AUDIO_102" title: "The requested media cannot be found" status: 404 '500': description: The requested data cannot be located content: application/json+problem: schema: $ref: './problem.yaml' example: type: "AUDIO_101" title: "The requested data cannot be located" status: 500 /audios/metadata: post: tags: - Audio summary: Upload audio metadata operationId: addAudioMetaData requestBody: content: application/json: schema: $ref: '#/components/schemas/AddAudioMetadataRequestWithStorageGUID' responses: '200': description: Audio metadata accepted '400': description: Bad request content: application/json+problem: schema: $ref: './problem.yaml' '500': description: Internal server error content: application/json+problem: schema: $ref: './problem.yaml' /admin/transformed-medias/{id}: get: tags: - Audio summary: Admin get transformed media operationId: adminGetTransformedMedia description: Returns a specific transformed media details parameters: - in: path name: id schema: type: integer required: true responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/GetTransformedMediaResponse' '403': description: Forbidden Error content: application/json+problem: schema: $ref: './problem.yaml' '404': description: Not Found Error content: application/json+problem: schema: $ref: './problem.yaml' example: type: "AUDIO_REQUESTS_103" title: "The requested transformed media cannot be found" status: 404 /admin/medias: get: tags: - Audio summary: Search for Media operationId: getAdminMedias description: Returns a representation of the media table which match the supplied search criteria. parameters: - in: query name: transformed_media_id schema: type: integer description: "Return media associated with this transformed_media_id." required: false - in: query name: hearing_ids schema: type: array items: type: integer description: "The hearing ids to search on" required: false - in: query name: start_at schema: type: string format: date-time description: "The start date to search on" required: false - in: query name: end_at schema: type: string format: date-time description: "The end date to search on" required: false responses: '200': description: OK content: application/json: schema: type: array items: $ref: '#/components/schemas/GetAdminMediaResponseItem' '422': description: Business Validation Error content: application/json+problem: schema: $ref: './problem.yaml' '400': description: Bad Request Error content: application/json+problem: schema: $ref: './problem.yaml' example: type: "AUDIO_109" title: "Either transformed_media_id must be provided in the request." status: 400 '401': description: Unauthorised Error content: application/json+problem: schema: $ref: './problem.yaml' example: type: "AUTHORISATION_100" title: "User is not authorised for the associated courthouse" status: 401 /admin/medias/{id}: patch: tags: - Audio operationId: patchAdminMediasById description: Update a media record parameters: - in: path name: id required: true schema: $ref: '#/components/schemas/MediaId' requestBody: required: true content: application/json: schema: type: object properties: is_current: type: boolean enum: [ true ] required: - is_current responses: '200': description: Accepted '422': description: Business Validation Error content: application/json+problem: schema: $ref: './problem.yaml' '400': description: Bad Request Error content: application/json+problem: schema: $ref: './problem.yaml' '401': description: Unauthorised Error content: application/json+problem: schema: $ref: './problem.yaml' '403': description: Forbidden Error content: application/json+problem: schema: allOf: - $ref: './problem.yaml' '404': description: Not Found Error content: application/json+problem: schema: $ref: './problem.yaml' '409': description: Data conflicting content: application/json+problem: schema: allOf: - $ref: './problem.yaml' get: tags: - Audio operationId: getAdminMediasById description: Returns a representation of a media record parameters: - in: path name: id required: true schema: $ref: '#/components/schemas/MediaId' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/AdminMediaResponse' /admin/medias/{id}/versions: get: tags: - Audio operationId: getAdminMediaVersionsById description: Returns a representation of a media record and associated versions parameters: - in: path name: id required: true schema: $ref: '#/components/schemas/MediaId' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/AdminVersionedMediaResponse' '401': description: Unauthorised Error '403': description: Forbidden Error content: application/json+problem: schema: allOf: - $ref: './problem.yaml' '404': description: Not Found Error content: application/json+problem: schema: allOf: - $ref: './problem.yaml' /admin/medias/{media_id}/hide: post: tags: - Audio summary: Hides or shows a Media operationId: postAdminHideMediaId parameters: - name: media_id in: path required: true schema: type: integer format: int64 requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/MediaHideRequest' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/MediaHideResponse' '401': description: Unauthorised Error '403': description: Forbidden Error content: application/json+problem: schema: allOf: - $ref: './problem.yaml' '409': description: Data conflicting content: application/json+problem: schema: allOf: - $ref: './problem.yaml' '404': description: Not Found Error content: application/json+problem: schema: allOf: - $ref: './problem.yaml' /admin/medias/{media_id}/approve-deletion: post: tags: - Audio summary: Approves deletion of media operationId: postAdminApproveMediaMarkedForDeletion parameters: - name: media_id in: path required: true schema: type: integer format: int64 responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/MediaApproveMarkedForDeletionResponse' '422': description: Business Validation Error content: application/json+problem: schema: $ref: './problem.yaml' '400': description: A required parameter is missing or an invalid datatype or value was provided for property. '409': description: Data conflicting content: application/json+problem: schema: allOf: - $ref: './problem.yaml' '404': description: Not Found Error content: application/json+problem: schema: allOf: - $ref: './problem.yaml' /admin/medias/search: post: tags: - Audio summary: |- Returns a representation of the media table which match the supplied search criteria. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PostAdminMediasSearchRequest' responses: '200': description: OK content: application/json: schema: type: array items: $ref: '#/components/schemas/PostAdminMediasSearchResponseItem' '422': description: Business Validation Error content: application/json+problem: schema: $ref: './problem.yaml' '400': description: A required parameter is missing or an invalid datatype or value was provided for property. '500': description: Internal Server Error /admin/medias/marked-for-deletion: get: tags: - Audio summary: |- Returns a representation of all media marked for deletion. responses: '200': description: OK content: application/json: schema: type: array items: $ref: '#/components/schemas/GetAdminMediasMarkedForDeletionItem' ######################################################################################################################## # COMPONENT DEFINITIONS ######################################################################################################################## components: schemas: GetAdminMediasMarkedForDeletionItem: type: object properties: media: type: array items: $ref: '#/components/schemas/GetAdminMediasMarkedForDeletionMediaItem' start_at: type: string format: date-time description: start timestamp end_at: type: string format: date-time description: end timestamp courthouse: $ref: '#/components/schemas/AdminMediaCourthouseResponse' courtroom: $ref: '#/components/schemas/AdminMediaCourtroomResponse' admin_action: $ref: '#/components/schemas/GetAdminMediasMarkedForDeletionAdminAction' required: - media - start_at - end_at - courthouse - courtroom - admin_action GetAdminMediasMarkedForDeletionAdminAction: type: object properties: ticket_reference: type: string example: "1234" hidden_by_id: type: integer example: 1 reason_id: type: integer example: 1 comments: type: array items: type: string required: - ticket_reference - hidden_by_id - reason_id - comments PostAdminMediasSearchRequest: type: object properties: courthouse_ids: type: array items: type: integer case_number: type: string example: 1234 maxLength: 32 courtroom_name: type: string example: "1" maxLength: 64 hearing_start_at: type: string format: date hearing_end_at: type: string format: date GetAdminMediasMarkedForDeletionMediaItem: type: object properties: id: type: integer example: 1 channel: type: integer example: 1 total_channels: type: integer example: 1 is_current: type: boolean example: true version_count: type: integer example: 1 required: - id - channel - total_channels - is_current - version_count PostAdminMediasSearchResponseItem: type: object properties: id: type: integer format: int64 example: 1 description: Unique media identifier, used internally by DARTS. courthouse: $ref: '#/components/schemas/AdminMediaCourthouseResponse' courtroom: $ref: '#/components/schemas/AdminMediaCourtroomResponse' start_at: type: string format: date-time description: start timestamp end_at: type: string format: date-time description: end timestamp channel: type: integer example: 1 is_hidden: type: boolean PostAdminMediasMarkedForDeletionItem: type: object properties: media_id: $ref: '#/components/schemas/MediaId' channel: $ref: '#/components/schemas/Channel' start_at: $ref: '#/components/schemas/StartAt' end_at: $ref: '#/components/schemas/EndAt' courthouse: $ref: '#/components/schemas/AdminMediaCourthouseResponse' courtroom: $ref: '#/components/schemas/AdminMediaCourtroomResponse' admin_action: $ref: '#/components/schemas/AdminActionResponse' AdminVersionedMediaResponse: type: object properties: media_object_id: type: string current_version: $ref: '#/components/schemas/AdminMediaVersionResponse' previous_versions: type: array items: $ref: '#/components/schemas/AdminMediaVersionResponse' AdminMediaVersionResponse: type: object properties: id: $ref: '#/components/schemas/MediaId' courthouse: $ref: '#/components/schemas/AdminMediaCourthouseResponse' courtroom: $ref: '#/components/schemas/AdminMediaCourtroomResponse' start_at: $ref: '#/components/schemas/StartAt' end_at: $ref: '#/components/schemas/EndAt' channel: $ref: '#/components/schemas/Channel' chronicle_id: $ref: '#/components/schemas/ChronicleId' antecedent_id: $ref: '#/components/schemas/AntecedentId' is_current: $ref: '#/components/schemas/IsCurrent' created_at: $ref: '#/components/schemas/CreatedAt' AdminMediaResponse: type: object properties: id: $ref: '#/components/schemas/MediaId' start_at: $ref: '#/components/schemas/StartAt' end_at: $ref: '#/components/schemas/EndAt' channel: $ref: '#/components/schemas/Channel' total_channels: $ref: '#/components/schemas/TotalChannels' media_type: $ref: '#/components/schemas/MediaType' media_format: $ref: '#/components/schemas/Format' file_size_bytes: $ref: '#/components/schemas/FileSize' filename: $ref: '#/components/schemas/Filename' media_object_id: $ref: '#/components/schemas/MediaObjectId' content_object_id: $ref: '#/components/schemas/ContentObjectId' clip_id: $ref: '#/components/schemas/ClipId' checksum: $ref: '#/components/schemas/Checksum' media_status: $ref: '#/components/schemas/MediaStatus' is_hidden: $ref: '#/components/schemas/Hidden' is_deleted: $ref: '#/components/schemas/Deleted' is_current: $ref: '#/components/schemas/IsCurrent' admin_action: $ref: '#/components/schemas/AdminActionResponse' version: $ref: '#/components/schemas/Version' chronicle_id: $ref: '#/components/schemas/ChronicleId' antecedent_id: $ref: '#/components/schemas/AntecedentId' retain_until: $ref: '#/components/schemas/RetainUntil' created_at: $ref: '#/components/schemas/CreatedAt' created_by_id: $ref: '#/components/schemas/CreatedBy' last_modified_at: $ref: '#/components/schemas/LastModifiedAt' last_modified_by_id: $ref: '#/components/schemas/LastModifiedBy' courthouse: $ref: '#/components/schemas/AdminMediaCourthouseResponse' courtroom: $ref: '#/components/schemas/AdminMediaCourtroomResponse' cases: type: array items: $ref: '#/components/schemas/AdminMediaCaseResponseItem' hearings: type: array items: $ref: '#/components/schemas/AdminMediaHearingResponseItem' AdminMediaCourthouseResponse: type: object properties: id: $ref: '#/components/schemas/CourthouseId' display_name: $ref: '#/components/schemas/CourthouseDisplayName' AdminMediaCourtroomResponse: type: object properties: id: $ref: '#/components/schemas/CourtroomId' name: $ref: '#/components/schemas/CourtroomName' AdminMediaCaseResponseItem: type: object description: | case_number and courthouse come from either court_case table or media_linked_case table 1. When cas_id exists: data is populated from court_case table including case number and full courthouse details 2. When cas_id is null: data is populated directly from media_linked_case table properties: id: type: integer description: 'The case id' nullable: true case_number: type: string description: 'The case number' source: type: string description: 'The source of the case' enum: [ 'Legacy', 'Add Audio Metadata', 'Add Audio Event Linking', 'Audio Linking Task' ] courthouse: type: object properties: id: $ref: '#/components/schemas/CourthouseId' nullable: true display_name: $ref: '#/components/schemas/CourthouseDisplayName' AdminMediaHearingResponseItem: type: object properties: id: $ref: '#/components/schemas/HearingId' is_data_anonymised: type: boolean case_id: $ref: '#/components/schemas/CaseId' case_number: type: string hearing_date: $ref: '#/components/schemas/HearingDate' courthouse: type: object properties: id: $ref: '#/components/schemas/CourthouseId' display_name: $ref: '#/components/schemas/CourthouseDisplayName' courtroom: type: object properties: id: $ref: '#/components/schemas/CourtroomId' name: $ref: '#/components/schemas/CourtroomName' GetAdminMediaResponseItem: type: object required: - id - channel - start_at - end_at - is_hidden - is_current properties: id: $ref: '#/components/schemas/MediaId' channel: $ref: '#/components/schemas/Channel' start_at: $ref: '#/components/schemas/StartAt' end_at: $ref: '#/components/schemas/EndAt' is_hidden: type: boolean is_current: type: boolean case: $ref: '#/components/schemas/GetAdminMediaResponseCase' hearing: $ref: '#/components/schemas/GetAdminMediaResponseHearing' courthouse: $ref: '#/components/schemas/GetAdminMediaResponseCourthouse' courtroom: $ref: '#/components/schemas/GetAdminMediaResponseCourtroom' GetAdminMediaResponseCase: type: object properties: id: $ref: '#/components/schemas/CaseId' case_number: type: string GetAdminMediaResponseHearing: type: object properties: id: $ref: '#/components/schemas/HearingId' hearing_date: $ref: '#/components/schemas/HearingDate' GetAdminMediaResponseCourthouse: type: object properties: id: $ref: '#/components/schemas/CourthouseId' display_name: $ref: '#/components/schemas/CourthouseDisplayName' GetAdminMediaResponseCourtroom: type: object properties: id: $ref: '#/components/schemas/CourtroomId' display_name: $ref: '#/components/schemas/CourtroomName' AudioMetadata: type: object properties: id: $ref: '#/components/schemas/MediaId' media_start_timestamp: type: string format: date-time media_end_timestamp: type: string format: date-time is_archived: type: boolean is_available: type: boolean file_size: type: integer format: int64 AddAudioMetadataRequestWithStorageGUID: allOf: # Combines the BasicErrorModel and the inline model - $ref: "#/components/schemas/AddAudioMetadataRequest" - type: object required: - storage_guid - checksum properties: storage_guid: type: string format: uuid AddAudioMetadataRequest: type: object required: - started_at - ended_at - channel - total_channels - format - filename - courthouse - courtroom - cases - file_size properties: started_at: type: string format: date-time description: 'Start timestamp of the audio recording' ended_at: type: string format: date-time description: 'End timestamp of the audio recording' channel: $ref: '#/components/schemas/Channel' total_channels: $ref: '#/components/schemas/TotalChannels' format: $ref: '#/components/schemas/Format' filename: $ref: '#/components/schemas/Filename' courthouse: type: string description: 'Courthouse the audio was recorded in' maxLength: 255 courtroom: type: string description: 'Courtroom the audio was recorded in' maxLength: 64 media_file: type: string description: 'The file for the audio' maxLength: 255 file_size: $ref: '#/components/schemas/FileSize' checksum: type: string description: 'Checksum to ensure integrity of file' maxLength: 255 cases: type: array items: type: string description: 'List of associated case numbers' minItems: 1 maxLength: 255 GetTransformedMediaResponse: type: object properties: id: type: integer file_name: type: string file_format: type: string file_size_bytes: type: integer case_id: type: integer media_request_id: type: integer MediaHideRequest: type: object required: - is_hidden properties: is_hidden: type: boolean admin_action: $ref: '#/components/schemas/AdminActionRequest' AdminActionRequest: type: object required: - reason_id - ticket_reference - comments properties: reason_id: type: integer ticket_reference: type: string comments: type: string MediaHideResponse: type: object properties: id: type: integer format: int64 description: 'The media id' is_hidden: type: boolean description: 'The media hidden state' is_deleted: type: boolean description: 'The media deleted state' admin_action: $ref: '#/components/schemas/AdminActionResponse' description: 'The media admin action data when the request was made' MediaApproveMarkedForDeletionResponse: allOf: - $ref: '#/components/schemas/MediaHideResponse' AdminActionResponse: type: object properties: id: type: integer description: 'The admin action id' reason_id: type: integer description: 'The admin action reason id' hidden_by_id: type: integer description: 'The user that made the entity hidden' hidden_at: type: string format: date-time description: 'The date and time that made the entity hidden' is_marked_for_manual_deletion: type: boolean description: 'The entity was manually marked for deletion' marked_for_manual_deletion_by_id: type: integer description: 'The user that marked the entity for deletion' marked_for_manual_deletion_at: type: string format: date-time description: 'The date and time that the entity was marked for deletion' ticket_reference: type: string description: 'The ticket reference for the admin action' comments: type: string description: 'The comments for the admin action' #################################################################################################################### # PRIMITIVES #################################################################################################################### MediaId: type: integer format: int64 description: med_id Format: type: string description: 'Media format of the audio recording' maxLength: 64 Filename: type: string description: 'Filename of the audio recording' maxLength: 255 MediaType: type: string maxLength: 255 FileSize: type: integer format: int64 description: 'The size of the file in bytes' Hidden: type: boolean Deleted: type: boolean CreatedAt: type: string format: date-time Channel: type: integer format: int32 description: 'Channel number of the audio recording' TotalChannels: type: integer format: int32 description: 'Number of channels making up the complete audio that this recording is part of' StartAt: type: string format: date-time EndAt: type: string format: date-time RetainUntil: type: string format: date-time AdminActionId: type: integer ReasonId: type: integer HiddenById: type: integer HiddenAt: type: string format: date-time MarkedForManualDeletion: type: boolean MarkedForDeletionById: type: integer MarkedForManualDeletionAt: type: string format: date-time TicketReference: type: string Comments: type: string HearingId: type: integer HearingDate: type: string format: date CaseId: type: integer CourthouseId: type: integer CourthouseDisplayName: type: string CourtroomId: type: integer CourtroomName: type: string ReferenceId: type: string Checksum: type: string MediaObjectId: type: string ContentObjectId: type: string ClipId: type: string ChronicleId: type: string AntecedentId: type: string MediaStatus: type: string Version: type: string CreatedBy: type: integer LastModifiedBy: type: integer LastModifiedAt: type: string format: date-time IsCurrent: type: boolean AddAudioErrorCode: type: string enum: - "AUDIO_100" - "AUDIO_101" - "AUDIO_102" - "AUDIO_103" - "AUDIO_104" - "AUDIO_110" - "AUDIO_111" - "AUDIO_112" - "AUDIO_113" - "AUDIO_115" - "AUDIO_116" - "AUDIO_117" - "AUDIO_118" - "AUDIO_119" - "AUDIO_120" - "AUDIO_121" - "AUDIO_122" - "AUDIO_123" x-enum-varnames: [ FAILED_TO_PROCESS_AUDIO_REQUEST, REQUESTED_DATA_CANNOT_BE_LOCATED, MEDIA_NOT_FOUND, FAILED_TO_UPLOAD_AUDIO_FILE, MISSING_SYSTEM_USER, MEDIA_ALREADY_HIDDEN, MEDIA_HIDE_ACTION_PAYLOAD_INCORRECT_USAGE, MEDIA_SHOW_ACTION_PAYLOAD_INCORRECT_USAGE, MEDIA_HIDE_ACTION_REASON_NOT_FOUND, ADMIN_SEARCH_CRITERIA_NOT_SUITABLE, TOO_MANY_RESULTS, MEDIA_ALREADY_MARKED_FOR_DELETION, ADMIN_MEDIA_MARKED_FOR_DELETION_NOT_FOUND, MARKED_FOR_DELETION_REASON_NOT_FOUND, USER_CANT_APPROVE_THEIR_OWN_DELETION, FAILED_TO_ADD_AUDIO_META_DATA, START_TIME_END_TIME_NOT_VALID, MEDIA_ALREADY_CURRENT ] AddAudioTitleErrors: type: string enum: - "Failed to process audio request" - "The requested data cannot be located" - "The requested media cannot be found" - "Failed to store uploaded audio file" - "Failed to mark audio(s) for deletion as system user was not found" - "Media is already hidden" - "Hide media action payload not correct" - "Showing media action payload not correct" - "Hide reason is incorrect" - "transformed_media_id OR one of hearing_id, start_at or end_at must be provided" - "Too many results" - "Already marked for deletion" - "Media marked for deletion not found" - "Media marked for deletion reason not found" - "User cannot approve their own deletion" - "Failed to add audio meta data" - "Start time or end time of media not valid" - "Media is already current" x-enum-varnames: [ FAILED_TO_PROCESS_AUDIO_REQUEST, REQUESTED_DATA_CANNOT_BE_LOCATED, MEDIA_NOT_FOUND, FAILED_TO_UPLOAD_AUDIO_FILE, MISSING_SYSTEM_USER, MEDIA_ALREADY_HIDDEN, MEDIA_HIDE_ACTION_PAYLOAD_INCORRECT_USAGE, MEDIA_SHOW_ACTION_PAYLOAD_INCORRECT_USAGE, MEDIA_HIDE_ACTION_REASON_NOT_FOUND, ADMIN_SEARCH_CRITERIA_NOT_SUITABLE, TOO_MANY_RESULTS, MEDIA_ALREADY_MARKED_FOR_DELETION, ADMIN_MEDIA_MARKED_FOR_DELETION_NOT_FOUND, MARKED_FOR_DELETION_REASON_NOT_FOUND, USER_CANT_APPROVE_THEIR_OWN_DELETION, FAILED_TO_ADD_AUDIO_META_DATA, START_TIME_END_TIME_NOT_VALID, MEDIA_ALREADY_CURRENT ]