@giveitsmaller/contracts 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/asyncapi/events.yaml +1777 -172
- package/availability/availability.json +2403 -0
- package/dist/asyncapi/AnonymousSchema_13.d.ts +6 -0
- package/dist/asyncapi/AnonymousSchema_13.js +7 -0
- package/dist/asyncapi/AnonymousSchema_152.d.ts +5 -0
- package/dist/asyncapi/AnonymousSchema_152.js +6 -0
- package/dist/asyncapi/Failure.d.ts +25 -0
- package/dist/asyncapi/Failure.js +1 -0
- package/dist/asyncapi/JobInputRole.d.ts +6 -0
- package/dist/asyncapi/JobInputRole.js +7 -0
- package/dist/asyncapi/MergeOutputType.d.ts +1 -3
- package/dist/asyncapi/MergeOutputType.js +0 -2
- package/dist/asyncapi/MultiOutputCompletion.d.ts +25 -0
- package/dist/asyncapi/MultiOutputCompletion.js +1 -0
- package/dist/asyncapi/NotificationsOperationsQueue.d.ts +4 -2
- package/dist/asyncapi/OperationMetrics.d.ts +3 -0
- package/dist/asyncapi/OperationProgress.d.ts +2 -0
- package/dist/asyncapi/OperationResult.d.ts +4 -19
- package/dist/asyncapi/OperationType.d.ts +6 -6
- package/dist/asyncapi/OperationType.js +5 -5
- package/dist/asyncapi/PageIndexed.d.ts +8 -0
- package/dist/asyncapi/PageIndexed.js +1 -0
- package/dist/asyncapi/PositionIndexed.d.ts +8 -0
- package/dist/asyncapi/PositionIndexed.js +1 -0
- package/dist/asyncapi/ProgressStatus.d.ts +3 -0
- package/dist/asyncapi/ProgressStatus.js +3 -0
- package/dist/asyncapi/ReEncodeDecision.d.ts +5 -0
- package/dist/asyncapi/ReEncodeDecision.js +6 -0
- package/dist/asyncapi/SingleOutputCompletion.d.ts +25 -0
- package/dist/asyncapi/SingleOutputCompletion.js +1 -0
- package/dist/asyncapi/SourceEntry.d.ts +2 -1
- package/dist/asyncapi/Unindexed.d.ts +8 -0
- package/dist/asyncapi/Unindexed.js +1 -0
- package/dist/asyncapi/UploadProbeCompletion.d.ts +16 -0
- package/dist/asyncapi/UploadProbeCompletion.js +1 -0
- package/dist/asyncapi/UploadProbeMediaMetadata.d.ts +18 -0
- package/dist/asyncapi/UploadProbeMediaMetadata.js +1 -0
- package/dist/asyncapi/UploadProbeProcessingClass.d.ts +6 -0
- package/dist/asyncapi/UploadProbeProcessingClass.js +7 -0
- package/dist/asyncapi/UploadProbeRequest.d.ts +10 -0
- package/dist/asyncapi/UploadProbeRequest.js +1 -0
- package/dist/asyncapi/UploadProbeStatus.d.ts +7 -0
- package/dist/asyncapi/UploadProbeStatus.js +8 -0
- package/dist/asyncapi/index.d.ts +13 -0
- package/dist/asyncapi/index.js +4 -0
- package/dist/openapi/models/AudioWatermarkDecodeRequest.d.ts +64 -0
- package/dist/openapi/models/AudioWatermarkDecodeRequest.js +53 -0
- package/dist/openapi/models/AudioWatermarkDecodeResponse.d.ts +80 -0
- package/dist/openapi/models/AudioWatermarkDecodeResponse.js +64 -0
- package/dist/openapi/models/AuthErrorResponse.d.ts +116 -0
- package/dist/openapi/models/AuthErrorResponse.js +66 -0
- package/dist/openapi/models/AuthErrorType.d.ts +73 -0
- package/dist/openapi/models/AuthErrorType.js +91 -0
- package/dist/openapi/models/AvailabilityValue.d.ts +43 -0
- package/dist/openapi/models/AvailabilityValue.js +61 -0
- package/dist/openapi/models/BalanceExhaustedResponse.d.ts +157 -0
- package/dist/openapi/models/BalanceExhaustedResponse.js +86 -0
- package/dist/openapi/models/BalanceExhaustedResponseAllOfLinks.d.ts +38 -0
- package/dist/openapi/models/BalanceExhaustedResponseAllOfLinks.js +43 -0
- package/dist/openapi/models/CallbackEventType.d.ts +2 -2
- package/dist/openapi/models/CallbackEventType.js +2 -2
- package/dist/openapi/models/ConnectionSource.d.ts +64 -0
- package/dist/openapi/models/ConnectionSource.js +57 -0
- package/dist/openapi/models/ContactRequest.d.ts +2 -2
- package/dist/openapi/models/ContactRequest.js +2 -2
- package/dist/openapi/models/ContactSubject.d.ts +2 -2
- package/dist/openapi/models/ContactSubject.js +2 -2
- package/dist/openapi/models/ContactValidationErrorResponse.d.ts +2 -2
- package/dist/openapi/models/ContactValidationErrorResponse.js +2 -2
- package/dist/openapi/models/CreateExternalImport403Response.d.ts +24 -0
- package/dist/openapi/models/CreateExternalImport403Response.js +58 -0
- package/dist/openapi/models/CreateWorkflow422Response.d.ts +23 -0
- package/dist/openapi/models/CreateWorkflow422Response.js +51 -0
- package/dist/openapi/models/CreditTransaction.d.ts +186 -0
- package/dist/openapi/models/CreditTransaction.js +100 -0
- package/dist/openapi/models/CreditTransactionSourceBucket.d.ts +46 -0
- package/dist/openapi/models/CreditTransactionSourceBucket.js +64 -0
- package/dist/openapi/models/CreditsBalanceResponse.d.ts +84 -0
- package/dist/openapi/models/CreditsBalanceResponse.js +68 -0
- package/dist/openapi/models/CreditsBalanceSuccessEnvelope.d.ts +46 -0
- package/dist/openapi/models/CreditsBalanceSuccessEnvelope.js +54 -0
- package/dist/openapi/models/CreditsUsageResponse.d.ts +51 -0
- package/dist/openapi/models/CreditsUsageResponse.js +56 -0
- package/dist/openapi/models/CreditsUsageSuccessEnvelope.d.ts +46 -0
- package/dist/openapi/models/CreditsUsageSuccessEnvelope.js +54 -0
- package/dist/openapi/models/Delivery.d.ts +98 -0
- package/dist/openapi/models/Delivery.js +65 -0
- package/dist/openapi/models/DeliveryOutputRef.d.ts +44 -0
- package/dist/openapi/models/DeliveryOutputRef.js +45 -0
- package/dist/openapi/models/DeliveryPlan.d.ts +77 -0
- package/dist/openapi/models/DeliveryPlan.js +72 -0
- package/dist/openapi/models/DeliveryPlanOutput.d.ts +53 -0
- package/dist/openapi/models/DeliveryPlanOutput.js +52 -0
- package/dist/openapi/models/DeliveryPlanReason.d.ts +35 -0
- package/dist/openapi/models/DeliveryPlanReason.js +53 -0
- package/dist/openapi/models/DeliverySelection.d.ts +62 -0
- package/dist/openapi/models/DeliverySelection.js +54 -0
- package/dist/openapi/models/ErrorEnvelope.d.ts +83 -5
- package/dist/openapi/models/ErrorEnvelope.js +10 -2
- package/dist/openapi/models/EstimateQuality.d.ts +34 -0
- package/dist/openapi/models/EstimateQuality.js +52 -0
- package/dist/openapi/models/EstimateRange.d.ts +48 -0
- package/dist/openapi/models/EstimateRange.js +51 -0
- package/dist/openapi/models/ExternalDestination.d.ts +41 -0
- package/dist/openapi/models/ExternalDestination.js +47 -0
- package/dist/openapi/models/ExternalImportCreatedResponse.d.ts +49 -0
- package/dist/openapi/models/ExternalImportCreatedResponse.js +51 -0
- package/dist/openapi/models/ExternalImportCreatedSuccessEnvelope.d.ts +46 -0
- package/dist/openapi/models/ExternalImportCreatedSuccessEnvelope.js +54 -0
- package/dist/openapi/models/ExternalImportRequest.d.ts +92 -0
- package/dist/openapi/models/ExternalImportRequest.js +61 -0
- package/dist/openapi/models/ExternalImportToken.d.ts +51 -0
- package/dist/openapi/models/ExternalImportToken.js +53 -0
- package/dist/openapi/models/ExternalSource.d.ts +31 -0
- package/dist/openapi/models/ExternalSource.js +47 -0
- package/dist/openapi/models/FeatureNotAvailableResponse.d.ts +140 -0
- package/dist/openapi/models/FeatureNotAvailableResponse.js +76 -0
- package/dist/openapi/models/FeatureTierRestrictedResponse.d.ts +135 -0
- package/dist/openapi/models/FeatureTierRestrictedResponse.js +76 -0
- package/dist/openapi/models/FeatureViolation.d.ts +108 -0
- package/dist/openapi/models/FeatureViolation.js +63 -0
- package/dist/openapi/models/JobDefinition.d.ts +125 -14
- package/dist/openapi/models/JobDefinition.js +25 -4
- package/dist/openapi/models/JobDownload.d.ts +2 -2
- package/dist/openapi/models/JobDownload.js +2 -2
- package/dist/openapi/models/JobInputV2.d.ts +89 -0
- package/dist/openapi/models/JobInputV2.js +56 -0
- package/dist/openapi/models/JobOutputSource.d.ts +57 -0
- package/dist/openapi/models/JobOutputSource.js +55 -0
- package/dist/openapi/models/JobResponse.d.ts +2 -2
- package/dist/openapi/models/JobResponse.js +2 -2
- package/dist/openapi/models/JobStatus.d.ts +17 -8
- package/dist/openapi/models/JobStatus.js +17 -8
- package/dist/openapi/models/JobType.d.ts +2 -2
- package/dist/openapi/models/JobType.js +2 -2
- package/dist/openapi/models/LivenessResponse.d.ts +2 -2
- package/dist/openapi/models/LivenessResponse.js +2 -2
- package/dist/openapi/models/LoginUser200Response.d.ts +46 -0
- package/dist/openapi/models/LoginUser200Response.js +54 -0
- package/dist/openapi/models/LoginUser200ResponseData.d.ts +33 -0
- package/dist/openapi/models/LoginUser200ResponseData.js +44 -0
- package/dist/openapi/models/LoginUser200ResponseDataUser.d.ts +50 -0
- package/dist/openapi/models/LoginUser200ResponseDataUser.js +51 -0
- package/dist/openapi/models/LoginUserRequest.d.ts +38 -0
- package/dist/openapi/models/LoginUserRequest.js +47 -0
- package/dist/openapi/models/LogoutUser200Response.d.ts +50 -0
- package/dist/openapi/models/LogoutUser200Response.js +53 -0
- package/dist/openapi/models/MetadataResponse.d.ts +13 -2
- package/dist/openapi/models/MetadataResponse.js +6 -2
- package/dist/openapi/models/MetadataResponseDimensions.d.ts +2 -2
- package/dist/openapi/models/MetadataResponseDimensions.js +2 -2
- package/dist/openapi/models/MetadataResponseExif.d.ts +2 -2
- package/dist/openapi/models/MetadataResponseExif.js +3 -3
- package/dist/openapi/models/MetadataResponseExifGps.d.ts +2 -2
- package/dist/openapi/models/MetadataResponseExifGps.js +2 -2
- package/dist/openapi/models/MetadataSuccessEnvelope.d.ts +3 -3
- package/dist/openapi/models/MetadataSuccessEnvelope.js +2 -2
- package/dist/openapi/models/MimeGroupSchema.d.ts +46 -2
- package/dist/openapi/models/MimeGroupSchema.js +11 -2
- package/dist/openapi/models/MultipartCompleteRequest.d.ts +3 -3
- package/dist/openapi/models/MultipartCompleteRequest.js +2 -2
- package/dist/openapi/models/MultipartCompleteRequestPartsInner.d.ts +2 -2
- package/dist/openapi/models/MultipartCompleteRequestPartsInner.js +2 -2
- package/dist/openapi/models/MultipartCompleteResponse.d.ts +7 -4
- package/dist/openapi/models/MultipartCompleteResponse.js +2 -2
- package/dist/openapi/models/MultipartCompleteSuccessEnvelope.d.ts +3 -3
- package/dist/openapi/models/MultipartCompleteSuccessEnvelope.js +2 -2
- package/dist/openapi/models/MultipartInitiateRequestMetadataHint.d.ts +56 -0
- package/dist/openapi/models/MultipartInitiateRequestMetadataHint.js +45 -0
- package/dist/openapi/models/MultipartInitiateResponse.d.ts +19 -3
- package/dist/openapi/models/MultipartInitiateResponse.js +7 -2
- package/dist/openapi/models/MultipartInitiateSuccessEnvelope.d.ts +3 -3
- package/dist/openapi/models/MultipartInitiateSuccessEnvelope.js +2 -2
- package/dist/openapi/models/OperationDefinition.d.ts +2 -2
- package/dist/openapi/models/OperationDefinition.js +2 -2
- package/dist/openapi/models/OperationDownload.d.ts +2 -2
- package/dist/openapi/models/OperationDownload.js +2 -2
- package/dist/openapi/models/OperationInputModel.d.ts +4 -4
- package/dist/openapi/models/OperationInputModel.js +4 -4
- package/dist/openapi/models/OperationResponse.d.ts +2 -2
- package/dist/openapi/models/OperationResponse.js +2 -2
- package/dist/openapi/models/OperationResult.d.ts +2 -2
- package/dist/openapi/models/OperationResult.js +2 -2
- package/dist/openapi/models/OperationResultMetrics.d.ts +2 -2
- package/dist/openapi/models/OperationResultMetrics.js +2 -2
- package/dist/openapi/models/OperationSchemaDefinition.d.ts +52 -5
- package/dist/openapi/models/OperationSchemaDefinition.js +10 -6
- package/dist/openapi/models/OperationStatus.d.ts +2 -2
- package/dist/openapi/models/OperationStatus.js +2 -2
- package/dist/openapi/models/OperationType.d.ts +17 -5
- package/dist/openapi/models/OperationType.js +18 -6
- package/dist/openapi/models/OperationsSchemaResponse.d.ts +70 -10
- package/dist/openapi/models/OperationsSchemaResponse.js +17 -2
- package/dist/openapi/models/OptionSchema.d.ts +42 -4
- package/dist/openapi/models/OptionSchema.js +12 -2
- package/dist/openapi/models/PerValueAvailabilityEntry.d.ts +80 -0
- package/dist/openapi/models/PerValueAvailabilityEntry.js +53 -0
- package/dist/openapi/models/PresignedUrlPart.d.ts +2 -2
- package/dist/openapi/models/PresignedUrlPart.js +3 -3
- package/dist/openapi/models/ProcessingClass.d.ts +35 -0
- package/dist/openapi/models/ProcessingClass.js +53 -0
- package/dist/openapi/models/ProcessingClassHint.d.ts +36 -0
- package/dist/openapi/models/ProcessingClassHint.js +54 -0
- package/dist/openapi/models/ProcessingClassReason.d.ts +46 -0
- package/dist/openapi/models/ProcessingClassReason.js +64 -0
- package/dist/openapi/models/ProcessingPlan.d.ts +70 -0
- package/dist/openapi/models/ProcessingPlan.js +49 -0
- package/dist/openapi/models/ProcessingPlanJob.d.ts +81 -0
- package/dist/openapi/models/ProcessingPlanJob.js +71 -0
- package/dist/openapi/models/ReadinessResponse.d.ts +2 -2
- package/dist/openapi/models/ReadinessResponse.js +2 -2
- package/dist/openapi/models/ResponseEnvelope.d.ts +2 -2
- package/dist/openapi/models/ResponseEnvelope.js +2 -2
- package/dist/openapi/models/RetryResponse.d.ts +5 -5
- package/dist/openapi/models/RetryResponse.js +2 -2
- package/dist/openapi/models/RetrySuccessEnvelope.d.ts +3 -3
- package/dist/openapi/models/RetrySuccessEnvelope.js +2 -2
- package/dist/openapi/models/SseEventType.d.ts +2 -2
- package/dist/openapi/models/SseEventType.js +2 -2
- package/dist/openapi/models/SseJobCompletedData.d.ts +3 -3
- package/dist/openapi/models/SseJobCompletedData.js +2 -2
- package/dist/openapi/models/SseJobFailedData.d.ts +3 -3
- package/dist/openapi/models/SseJobFailedData.js +2 -2
- package/dist/openapi/models/SseOperationCompletedData.d.ts +4 -4
- package/dist/openapi/models/SseOperationCompletedData.js +2 -2
- package/dist/openapi/models/SseOperationFailedData.d.ts +3 -3
- package/dist/openapi/models/SseOperationFailedData.js +2 -2
- package/dist/openapi/models/SseOperationProgressData.d.ts +61 -3
- package/dist/openapi/models/SseOperationProgressData.js +22 -2
- package/dist/openapi/models/SseWorkflowTerminalData.d.ts +26 -4
- package/dist/openapi/models/SseWorkflowTerminalData.js +4 -2
- package/dist/openapi/models/TierRestrictionKind.d.ts +33 -0
- package/dist/openapi/models/TierRestrictionKind.js +51 -0
- package/dist/openapi/models/TierRestrictionResponse.d.ts +154 -0
- package/dist/openapi/models/TierRestrictionResponse.js +83 -0
- package/dist/openapi/models/UploadConstraintsApplied.d.ts +70 -0
- package/dist/openapi/models/UploadConstraintsApplied.js +57 -0
- package/dist/openapi/models/UploadDurationExceedsTierResponse.d.ts +136 -0
- package/dist/openapi/models/UploadDurationExceedsTierResponse.js +82 -0
- package/dist/openapi/models/UploadFile403Response.d.ts +27 -0
- package/dist/openapi/models/UploadFile403Response.js +47 -0
- package/dist/openapi/models/UploadFile422Response.d.ts +27 -0
- package/dist/openapi/models/UploadFile422Response.js +47 -0
- package/dist/openapi/models/UploadProbeMediaMetadata.d.ts +172 -0
- package/dist/openapi/models/UploadProbeMediaMetadata.js +69 -0
- package/dist/openapi/models/UploadProbeProcessingClass.d.ts +33 -0
- package/dist/openapi/models/UploadProbeProcessingClass.js +51 -0
- package/dist/openapi/models/UploadProbeResponse.d.ts +58 -0
- package/dist/openapi/models/UploadProbeResponse.js +58 -0
- package/dist/openapi/models/UploadProbeStatus.d.ts +41 -0
- package/dist/openapi/models/UploadProbeStatus.js +59 -0
- package/dist/openapi/models/UploadResponse.d.ts +17 -3
- package/dist/openapi/models/UploadResponse.js +7 -2
- package/dist/openapi/models/UploadSizeExceedsTierResponse.d.ts +136 -0
- package/dist/openapi/models/UploadSizeExceedsTierResponse.js +82 -0
- package/dist/openapi/models/UploadSource.d.ts +48 -0
- package/dist/openapi/models/UploadSource.js +53 -0
- package/dist/openapi/models/UploadSuccessEnvelope.d.ts +3 -3
- package/dist/openapi/models/UploadSuccessEnvelope.js +2 -2
- package/dist/openapi/models/UploadThresholds.d.ts +119 -0
- package/dist/openapi/models/UploadThresholds.js +79 -0
- package/dist/openapi/models/UserTier.d.ts +41 -0
- package/dist/openapi/models/UserTier.js +59 -0
- package/dist/openapi/models/ValidationErrorEnvelope.d.ts +51 -4
- package/dist/openapi/models/ValidationErrorEnvelope.js +10 -2
- package/dist/openapi/models/ValidationErrorEnvelopeDetailsInner.d.ts +37 -4
- package/dist/openapi/models/ValidationErrorEnvelopeDetailsInner.js +6 -2
- package/dist/openapi/models/WarningType.d.ts +48 -0
- package/dist/openapi/models/WarningType.js +66 -0
- package/dist/openapi/models/WebhookOperationContext.d.ts +3 -3
- package/dist/openapi/models/WebhookOperationContext.js +2 -2
- package/dist/openapi/models/WebhookPayload.d.ts +2 -2
- package/dist/openapi/models/WebhookPayload.js +3 -3
- package/dist/openapi/models/WorkflowCancelBillingEffect.d.ts +36 -0
- package/dist/openapi/models/WorkflowCancelBillingEffect.js +54 -0
- package/dist/openapi/models/WorkflowCancelResponse.d.ts +66 -0
- package/dist/openapi/models/WorkflowCancelResponse.js +62 -0
- package/dist/openapi/models/WorkflowCancelSuccessEnvelope.d.ts +46 -0
- package/dist/openapi/models/WorkflowCancelSuccessEnvelope.js +54 -0
- package/dist/openapi/models/WorkflowCreateRequest.d.ts +39 -5
- package/dist/openapi/models/WorkflowCreateRequest.js +11 -5
- package/dist/openapi/models/WorkflowCreateResponse.d.ts +63 -2
- package/dist/openapi/models/WorkflowCreateResponse.js +21 -2
- package/dist/openapi/models/WorkflowCreateSuccessEnvelope.d.ts +3 -3
- package/dist/openapi/models/WorkflowCreateSuccessEnvelope.js +2 -2
- package/dist/openapi/models/WorkflowDownloadResponse.d.ts +2 -2
- package/dist/openapi/models/WorkflowDownloadResponse.js +2 -2
- package/dist/openapi/models/WorkflowDownloadSuccessEnvelope.d.ts +3 -3
- package/dist/openapi/models/WorkflowDownloadSuccessEnvelope.js +2 -2
- package/dist/openapi/models/WorkflowEdge.d.ts +2 -2
- package/dist/openapi/models/WorkflowEdge.js +2 -2
- package/dist/openapi/models/WorkflowExpiredResponse.d.ts +126 -0
- package/dist/openapi/models/WorkflowExpiredResponse.js +75 -0
- package/dist/openapi/models/WorkflowPauseRequiredAction.d.ts +30 -0
- package/dist/openapi/models/WorkflowPauseRequiredAction.js +48 -0
- package/dist/openapi/models/WorkflowPausedDetail.d.ts +99 -0
- package/dist/openapi/models/WorkflowPausedDetail.js +65 -0
- package/dist/openapi/models/WorkflowPausedDetailLinks.d.ts +47 -0
- package/dist/openapi/models/WorkflowPausedDetailLinks.js +45 -0
- package/dist/openapi/models/WorkflowProcessing.d.ts +36 -0
- package/dist/openapi/models/WorkflowProcessing.js +42 -0
- package/dist/openapi/models/WorkflowResumeResponse.d.ts +55 -0
- package/dist/openapi/models/WorkflowResumeResponse.js +57 -0
- package/dist/openapi/models/WorkflowResumeSuccessEnvelope.d.ts +46 -0
- package/dist/openapi/models/WorkflowResumeSuccessEnvelope.js +54 -0
- package/dist/openapi/models/WorkflowSource.d.ts +40 -0
- package/dist/openapi/models/WorkflowSource.js +57 -0
- package/dist/openapi/models/WorkflowStatus.d.ts +31 -8
- package/dist/openapi/models/WorkflowStatus.js +32 -9
- package/dist/openapi/models/WorkflowStatusResponse.d.ts +34 -2
- package/dist/openapi/models/WorkflowStatusResponse.js +13 -2
- package/dist/openapi/models/WorkflowStatusSuccessEnvelope.d.ts +3 -3
- package/dist/openapi/models/WorkflowStatusSuccessEnvelope.js +2 -2
- package/dist/openapi/models/WorkflowWarning.d.ts +119 -0
- package/dist/openapi/models/WorkflowWarning.js +63 -0
- package/dist/openapi/models/WorkflowWarningSeverity.d.ts +29 -0
- package/dist/openapi/models/WorkflowWarningSeverity.js +47 -0
- package/dist/openapi/models/index.d.ts +75 -3
- package/dist/openapi/models/index.js +75 -3
- package/dist/openapi/runtime.d.ts +2 -2
- package/dist/openapi/runtime.js +17 -2
- package/dist/operations/archive.metadata.d.ts +2 -0
- package/dist/operations/archive.metadata.js +13 -0
- package/dist/operations/audio_overlay.d.ts +48 -0
- package/dist/operations/audio_overlay.js +19 -0
- package/dist/operations/audio_overlay.metadata.d.ts +2 -0
- package/dist/operations/audio_overlay.metadata.js +167 -0
- package/dist/operations/audio_watermark.d.ts +42 -0
- package/dist/operations/audio_watermark.js +37 -0
- package/dist/operations/audio_watermark.metadata.d.ts +2 -0
- package/dist/operations/audio_watermark.metadata.js +94 -0
- package/dist/operations/compress.metadata.d.ts +2 -0
- package/dist/operations/compress.metadata.js +205 -0
- package/dist/operations/convert.metadata.d.ts +2 -0
- package/dist/operations/convert.metadata.js +85 -0
- package/dist/operations/custom_luma.d.ts +7 -0
- package/dist/operations/custom_luma.js +2 -0
- package/dist/operations/custom_luma.metadata.d.ts +2 -0
- package/dist/operations/custom_luma.metadata.js +49 -0
- package/dist/operations/image_watermark.d.ts +54 -0
- package/dist/operations/image_watermark.js +37 -0
- package/dist/operations/image_watermark.metadata.d.ts +2 -0
- package/dist/operations/image_watermark.metadata.js +97 -0
- package/dist/operations/index.d.ts +16 -1
- package/dist/operations/index.js +16 -1
- package/dist/operations/merge.d.ts +111 -31
- package/dist/operations/merge.js +106 -20
- package/dist/operations/merge.metadata.d.ts +2 -0
- package/dist/operations/merge.metadata.js +385 -0
- package/dist/operations/metadata-types.d.ts +47 -0
- package/dist/operations/metadata-types.js +2 -0
- package/dist/operations/text_watermark.d.ts +31 -0
- package/dist/operations/text_watermark.js +22 -0
- package/dist/operations/text_watermark.metadata.d.ts +2 -0
- package/dist/operations/text_watermark.metadata.js +46 -0
- package/dist/operations/thumbnail.metadata.d.ts +2 -0
- package/dist/operations/thumbnail.metadata.js +88 -0
- package/openapi/api.yaml +5070 -449
- package/operations/schemas/audio_overlay.yaml +397 -0
- package/operations/schemas/audio_watermark.yaml +184 -0
- package/operations/schemas/compress.yaml +20 -3
- package/operations/schemas/convert.yaml +18 -3
- package/operations/schemas/custom_luma.yaml +109 -0
- package/operations/schemas/image_watermark.yaml +280 -0
- package/operations/schemas/merge.yaml +295 -66
- package/operations/schemas/text_watermark.yaml +147 -0
- package/operations/schemas/thumbnail.yaml +15 -0
- package/package.json +10 -4
- package/operations/schemas/watermark.yaml +0 -87
package/asyncapi/events.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
asyncapi: 3.0.0
|
|
2
2
|
info:
|
|
3
3
|
title: GISL Compression Events
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.2.0
|
|
5
5
|
description: |
|
|
6
6
|
Asynchronous event contracts for the GISL (Give It Smaller) compression service.
|
|
7
7
|
|
|
@@ -16,9 +16,16 @@ info:
|
|
|
16
16
|
(`jobs-image`, `jobs-video`, `jobs-audio`, `jobs-document`). Each
|
|
17
17
|
compression Lambda handles `compress` for exactly one media type.
|
|
18
18
|
- **`gisl-{env}-{region}-operations`** — non-compression operations
|
|
19
|
-
(thumbnail,
|
|
19
|
+
(thumbnail, image_watermark, text_watermark, merge, archive, convert,
|
|
20
|
+
custom_luma, audio_overlay, audio_watermark). Filter attribute:
|
|
20
21
|
`operation_type`. Subscriptions: one queue per operation type, plus four
|
|
21
|
-
thumbnail sub-type queues during the migration window.
|
|
22
|
+
thumbnail sub-type queues during the migration window. `custom_luma`,
|
|
23
|
+
`audio_overlay`, and `audio_watermark` are `availability: planned`
|
|
24
|
+
(per [I29](https://trello.com/c/EPUE5Vs1) +
|
|
25
|
+
[I19](https://trello.com/c/Xr3Z4GBF) +
|
|
26
|
+
[I20](https://trello.com/c/omiCq7Vn)) — their queues are declared
|
|
27
|
+
but receive no traffic until Lambda ships. `audio_watermark`
|
|
28
|
+
additionally requires `enterprise` tier.
|
|
22
29
|
|
|
23
30
|
**Publisher branching rule** (implemented in `compression_api`'s
|
|
24
31
|
`AwsSnsOperationPublisherAdapter` under Option A):
|
|
@@ -64,8 +71,13 @@ info:
|
|
|
64
71
|
`operation-thumbnail` (legacy, retiring after migration),
|
|
65
72
|
`operation-thumbnail-image`, `operation-thumbnail-video`,
|
|
66
73
|
`operation-thumbnail-document`, `operation-thumbnail-office`,
|
|
67
|
-
`operation-watermark`, `operation-
|
|
68
|
-
`operation-
|
|
74
|
+
`operation-image-watermark`, `operation-text-watermark`,
|
|
75
|
+
`operation-merge`, `operation-archive`,
|
|
76
|
+
`operation-convert`,
|
|
77
|
+
`operation-custom-luma` (planned per ticket I29 — not yet shipped),
|
|
78
|
+
`operation-audio-overlay` (planned per ticket I19 — not yet shipped),
|
|
79
|
+
`operation-audio-watermark` (planned per ticket I20 —
|
|
80
|
+
enterprise-tier; not yet shipped).
|
|
69
81
|
|
|
70
82
|
**Message Types**
|
|
71
83
|
|
|
@@ -81,6 +93,22 @@ info:
|
|
|
81
93
|
and `OperationRequestAttributes`) so each topic's required attributes can
|
|
82
94
|
be enforced cleanly without conditional discriminators.
|
|
83
95
|
|
|
96
|
+
**Availability metadata.**
|
|
97
|
+
|
|
98
|
+
This spec uses the `x-availability` vendor extension as **decorative
|
|
99
|
+
documentation only**. Per [ADR-0001](../docs/decisions/0001-contract-first-availability.md)
|
|
100
|
+
§1.5, the runtime endpoint `GET /api/operations/schema` (ticket I3) is
|
|
101
|
+
the authoritative source; the sidecar `availability.json` (ticket I3b)
|
|
102
|
+
is the authoritative companion. SDKs MUST NOT depend on
|
|
103
|
+
`x-availability` reaching generated code — consumers read availability
|
|
104
|
+
from the runtime endpoint, not from the generated bindings.
|
|
105
|
+
|
|
106
|
+
The 5-value vocabulary (`stable | beta | experimental | planned |
|
|
107
|
+
deprecated`) is defined in the `AvailabilityValue` schema. See
|
|
108
|
+
`schemas/FORMAT.md` §Availability Taxonomy for operational rules
|
|
109
|
+
(parser obligation: absent = stable; per-enum-value granularity lands
|
|
110
|
+
via ticket I17 `per_value_availability` primitive).
|
|
111
|
+
|
|
84
112
|
servers:
|
|
85
113
|
local:
|
|
86
114
|
host: localhost:4566
|
|
@@ -131,7 +159,7 @@ channels:
|
|
|
131
159
|
address: gisl-{env}-{region}-operations
|
|
132
160
|
description: |
|
|
133
161
|
SNS topic where the API publishes **non-compression** operation
|
|
134
|
-
requests (thumbnail,
|
|
162
|
+
requests (thumbnail, image_watermark, text_watermark, merge, archive, convert, custom_luma, audio_overlay, audio_watermark). Filter
|
|
135
163
|
attribute: `operation_type` (single-attribute filter policy).
|
|
136
164
|
Subscriptions fan out to per-operation-type queues, keyed by
|
|
137
165
|
`operation_type` value.
|
|
@@ -142,10 +170,25 @@ channels:
|
|
|
142
170
|
- `operation_type = thumbnail_video` -> `ops-thumbnail-video` queue
|
|
143
171
|
- `operation_type = thumbnail_document` -> `ops-thumbnail-document` queue
|
|
144
172
|
- `operation_type = thumbnail_office` -> `ops-thumbnail-office` queue
|
|
145
|
-
- `operation_type =
|
|
173
|
+
- `operation_type = image_watermark` -> `ops-image-watermark` queue
|
|
174
|
+
- `operation_type = text_watermark` -> `ops-text-watermark` queue
|
|
146
175
|
- `operation_type = merge` -> `ops-merge` queue
|
|
147
176
|
- `operation_type = archive` -> `ops-archive` queue
|
|
148
177
|
- `operation_type = convert` -> `ops-convert` queue
|
|
178
|
+
- `operation_type = custom_luma` -> `ops-custom-luma` queue (gated
|
|
179
|
+
by `availability: planned` until Lambda ships per
|
|
180
|
+
[I29](https://trello.com/c/EPUE5Vs1) — API rejects workflow-
|
|
181
|
+
create with `feature_not_available` (422) so no traffic reaches
|
|
182
|
+
the topic today)
|
|
183
|
+
- `operation_type = audio_overlay` -> `ops-audio-overlay` queue
|
|
184
|
+
(gated by `availability: planned` until Lambda ships per
|
|
185
|
+
[I19](https://trello.com/c/Xr3Z4GBF) — same `feature_not_
|
|
186
|
+
available` 422 gating)
|
|
187
|
+
- `operation_type = audio_watermark` -> `ops-audio-watermark`
|
|
188
|
+
queue (gated by `availability: planned` +
|
|
189
|
+
`required_tier: enterprise` per
|
|
190
|
+
[I20](https://trello.com/c/omiCq7Vn) — same 422 gating, plus
|
|
191
|
+
a 403 `feature_tier_restricted` for non-enterprise callers)
|
|
149
192
|
|
|
150
193
|
The API's Option A publisher sets `operation_type` as the filter
|
|
151
194
|
attribute and additionally sets `media_group` as an **informational**
|
|
@@ -382,14 +425,41 @@ channels:
|
|
|
382
425
|
operationRequest:
|
|
383
426
|
$ref: '#/components/messages/OperationRequestMessage'
|
|
384
427
|
|
|
385
|
-
|
|
386
|
-
address: gisl-{env}-{region}-ops-watermark
|
|
428
|
+
opsImageWatermark:
|
|
429
|
+
address: gisl-{env}-{region}-ops-image-watermark
|
|
430
|
+
description: |
|
|
431
|
+
SQS queue for image_watermark operations (multi-input).
|
|
432
|
+
Subscribed to the `operations` SNS topic with filter
|
|
433
|
+
`operation_type = image_watermark`. Handles image-overlay
|
|
434
|
+
watermarking with one `base` input + one `overlay` input
|
|
435
|
+
(per JobInputV2.role). Backed by the operation-image-watermark
|
|
436
|
+
Lambda (cross-repo X1 retirement target).
|
|
437
|
+
|
|
438
|
+
Stable today for image bases (jpeg/png/webp). Animated GIF and
|
|
439
|
+
video bases are advertised in `image_watermark.yaml` as `planned`
|
|
440
|
+
via parallel mime_groups (`image_gif`, `video` per I5 — Trello
|
|
441
|
+
AKZiOXnd); the publisher MAY route those `media_group` values to
|
|
442
|
+
this queue once Lambda support ships. Until then the API returns
|
|
443
|
+
`feature_not_available` (422) at workflow-create time and these
|
|
444
|
+
messages do not reach the queue. Per ADR-0004 + I4-CONS + I5.
|
|
445
|
+
parameters:
|
|
446
|
+
env:
|
|
447
|
+
description: Environment (local, stg, prod)
|
|
448
|
+
region:
|
|
449
|
+
description: AWS region abbreviation (euw1, use1, etc.)
|
|
450
|
+
messages:
|
|
451
|
+
operationRequest:
|
|
452
|
+
$ref: '#/components/messages/OperationRequestMessage'
|
|
453
|
+
|
|
454
|
+
opsTextWatermark:
|
|
455
|
+
address: gisl-{env}-{region}-ops-text-watermark
|
|
387
456
|
description: |
|
|
388
|
-
SQS queue for
|
|
457
|
+
SQS queue for text_watermark operations (single-input, image-only).
|
|
389
458
|
Subscribed to the `operations` SNS topic with filter
|
|
390
|
-
`operation_type =
|
|
391
|
-
|
|
392
|
-
(
|
|
459
|
+
`operation_type = text_watermark`. Renders text overlays
|
|
460
|
+
(Liberation Sans) — supports `single` (one label at anchor) and
|
|
461
|
+
`tiled` (Cinavia-style angled fill) modes. Backed by the
|
|
462
|
+
operation-text-watermark Lambda. Per ADR-0004 + I4-CONS.
|
|
393
463
|
parameters:
|
|
394
464
|
env:
|
|
395
465
|
description: Environment (local, stg, prod)
|
|
@@ -405,10 +475,10 @@ channels:
|
|
|
405
475
|
SQS queue for merge operations.
|
|
406
476
|
Subscribed to the `operations` SNS topic with filter
|
|
407
477
|
`operation_type = merge`. A single `operation-merge` Lambda handles
|
|
408
|
-
all merge output types (
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
the
|
|
478
|
+
all merge output types (animated GIF, video slideshow/concat, audio
|
|
479
|
+
concat) — the `output_type` field on the request determines the
|
|
480
|
+
encoding path internally, not the routing. Image collage and PDF
|
|
481
|
+
concatenation are not supported by the V1 Lambda.
|
|
412
482
|
parameters:
|
|
413
483
|
env:
|
|
414
484
|
description: Environment (local, stg, prod)
|
|
@@ -451,6 +521,97 @@ channels:
|
|
|
451
521
|
operationRequest:
|
|
452
522
|
$ref: '#/components/messages/OperationRequestMessage'
|
|
453
523
|
|
|
524
|
+
opsCustomLuma:
|
|
525
|
+
address: gisl-{env}-{region}-ops-custom-luma
|
|
526
|
+
description: |
|
|
527
|
+
SQS queue for custom_luma operations (caller-uploaded luma matte
|
|
528
|
+
transition; pro-tier paid feature). Subscribed to the
|
|
529
|
+
`operations` SNS topic with filter `operation_type = custom_luma`.
|
|
530
|
+
Multi-input (Path B with `role: base` + `role: transition_mask`
|
|
531
|
+
per `JobInputV2.role`).
|
|
532
|
+
|
|
533
|
+
`custom_luma` is `availability: planned` + `required_tier: pro`
|
|
534
|
+
per the operation schema; the API rejects workflow-create with
|
|
535
|
+
`feature_not_available` (422) until the Lambda ships, so traffic
|
|
536
|
+
does not reach this queue today. Backed by the
|
|
537
|
+
`operation-custom-luma` Lambda (cross-repo follow-up; not yet
|
|
538
|
+
shipped).
|
|
539
|
+
Per ADR-0004 + I29 (Trello EPUE5Vs1).
|
|
540
|
+
parameters:
|
|
541
|
+
env:
|
|
542
|
+
description: Environment (local, stg, prod)
|
|
543
|
+
region:
|
|
544
|
+
description: AWS region abbreviation (euw1, use1, etc.)
|
|
545
|
+
messages:
|
|
546
|
+
operationRequest:
|
|
547
|
+
$ref: '#/components/messages/OperationRequestMessage'
|
|
548
|
+
|
|
549
|
+
opsAudioOverlay:
|
|
550
|
+
address: gisl-{env}-{region}-ops-audio-overlay
|
|
551
|
+
description: |
|
|
552
|
+
SQS queue for audio_overlay operations (mix a secondary audio
|
|
553
|
+
asset over a primary audio or video base — DJ tags, podcast
|
|
554
|
+
intros/outros, station IDs, jingles). Subscribed to the
|
|
555
|
+
`operations` SNS topic with filter
|
|
556
|
+
`operation_type = audio_overlay`. Multi-input (Path B with
|
|
557
|
+
`role: base` + `role: overlay` per `JobInputV2.role`).
|
|
558
|
+
|
|
559
|
+
Both mime_groups (`audio`, `video`) are `availability: planned`;
|
|
560
|
+
the API rejects workflow-create with `feature_not_available`
|
|
561
|
+
(422) until the Lambda ships, so traffic does not reach this
|
|
562
|
+
queue today. Backed by the `operation-audio-overlay` Lambda
|
|
563
|
+
(cross-repo follow-up; not yet shipped).
|
|
564
|
+
|
|
565
|
+
**NOT** the same as `audio_watermark` — that operation is
|
|
566
|
+
steganographic (imperceptible identifier embedded in audio for
|
|
567
|
+
ownership / forensic tracking) and is owned by ticket I20
|
|
568
|
+
(Trello omiCq7Vn). `audio_overlay` is industry "audio overlay"
|
|
569
|
+
/ "audio branding".
|
|
570
|
+
|
|
571
|
+
Per ADR-0004 + I19 (Trello Xr3Z4GBF).
|
|
572
|
+
parameters:
|
|
573
|
+
env:
|
|
574
|
+
description: Environment (local, stg, prod)
|
|
575
|
+
region:
|
|
576
|
+
description: AWS region abbreviation (euw1, use1, etc.)
|
|
577
|
+
messages:
|
|
578
|
+
operationRequest:
|
|
579
|
+
$ref: '#/components/messages/OperationRequestMessage'
|
|
580
|
+
|
|
581
|
+
opsAudioWatermark:
|
|
582
|
+
address: gisl-{env}-{region}-ops-audio-watermark
|
|
583
|
+
description: |
|
|
584
|
+
SQS queue for audio_watermark operations (steganographic
|
|
585
|
+
forensic watermarking — Cinavia / Resemble PerTh territory).
|
|
586
|
+
Subscribed to the `operations` SNS topic with filter
|
|
587
|
+
`operation_type = audio_watermark`. Single-input.
|
|
588
|
+
|
|
589
|
+
Both mime_groups (`audio`, `video` — embed in video's audio
|
|
590
|
+
track) are `availability: planned` + `required_tier:
|
|
591
|
+
enterprise` per the operation schema; the API rejects workflow-
|
|
592
|
+
create with `feature_not_available` (422) until the Lambda
|
|
593
|
+
ships, plus 403 `feature_tier_restricted` for non-enterprise
|
|
594
|
+
callers, so traffic does not reach this queue today. Backed
|
|
595
|
+
by the `operation-audio-watermark` Lambda (cross-repo follow-up;
|
|
596
|
+
not yet shipped).
|
|
597
|
+
|
|
598
|
+
**Industry naming.** This is *audio watermarking* (steganographic
|
|
599
|
+
ownership / forensic tracking), NOT *audio overlay* (audible
|
|
600
|
+
mixing). Audio overlay is owned by `audio_overlay` (I19).
|
|
601
|
+
|
|
602
|
+
Pairs with `POST /api/audio-watermark/decode` for
|
|
603
|
+
own-watermarks-only extraction (declared in `openapi/api.yaml`).
|
|
604
|
+
|
|
605
|
+
Per ADR-0004 + I20 (Trello omiCq7Vn).
|
|
606
|
+
parameters:
|
|
607
|
+
env:
|
|
608
|
+
description: Environment (local, stg, prod)
|
|
609
|
+
region:
|
|
610
|
+
description: AWS region abbreviation (euw1, use1, etc.)
|
|
611
|
+
messages:
|
|
612
|
+
operationRequest:
|
|
613
|
+
$ref: '#/components/messages/OperationRequestMessage'
|
|
614
|
+
|
|
454
615
|
# ============================================
|
|
455
616
|
# OPS FAMILY - DEAD LETTER QUEUES
|
|
456
617
|
# ============================================
|
|
@@ -500,9 +661,18 @@ channels:
|
|
|
500
661
|
region:
|
|
501
662
|
description: AWS region abbreviation (euw1, use1, etc.)
|
|
502
663
|
|
|
503
|
-
|
|
504
|
-
address: gisl-{env}-{region}-ops-watermark-dlq
|
|
505
|
-
description: DLQ for failed
|
|
664
|
+
opsImageWatermarkDlq:
|
|
665
|
+
address: gisl-{env}-{region}-ops-image-watermark-dlq
|
|
666
|
+
description: DLQ for failed image_watermark operations. Messages land here after 5 failed processing attempts.
|
|
667
|
+
parameters:
|
|
668
|
+
env:
|
|
669
|
+
description: Environment (local, stg, prod)
|
|
670
|
+
region:
|
|
671
|
+
description: AWS region abbreviation (euw1, use1, etc.)
|
|
672
|
+
|
|
673
|
+
opsTextWatermarkDlq:
|
|
674
|
+
address: gisl-{env}-{region}-ops-text-watermark-dlq
|
|
675
|
+
description: DLQ for failed text_watermark operations. Messages land here after 5 failed processing attempts.
|
|
506
676
|
parameters:
|
|
507
677
|
env:
|
|
508
678
|
description: Environment (local, stg, prod)
|
|
@@ -536,6 +706,152 @@ channels:
|
|
|
536
706
|
region:
|
|
537
707
|
description: AWS region abbreviation (euw1, use1, etc.)
|
|
538
708
|
|
|
709
|
+
opsCustomLumaDlq:
|
|
710
|
+
address: gisl-{env}-{region}-ops-custom-luma-dlq
|
|
711
|
+
description: |
|
|
712
|
+
DLQ for failed custom_luma operations (per ticket I29).
|
|
713
|
+
Messages land here after 5 failed processing attempts. No traffic
|
|
714
|
+
reaches this queue while custom_luma is `availability: planned`.
|
|
715
|
+
parameters:
|
|
716
|
+
env:
|
|
717
|
+
description: Environment (local, stg, prod)
|
|
718
|
+
region:
|
|
719
|
+
description: AWS region abbreviation (euw1, use1, etc.)
|
|
720
|
+
|
|
721
|
+
opsAudioOverlayDlq:
|
|
722
|
+
address: gisl-{env}-{region}-ops-audio-overlay-dlq
|
|
723
|
+
description: |
|
|
724
|
+
DLQ for failed audio_overlay operations (per ticket I19).
|
|
725
|
+
Messages land here after 5 failed processing attempts. No
|
|
726
|
+
traffic reaches this queue while audio_overlay is
|
|
727
|
+
`availability: planned`.
|
|
728
|
+
parameters:
|
|
729
|
+
env:
|
|
730
|
+
description: Environment (local, stg, prod)
|
|
731
|
+
region:
|
|
732
|
+
description: AWS region abbreviation (euw1, use1, etc.)
|
|
733
|
+
|
|
734
|
+
opsAudioWatermarkDlq:
|
|
735
|
+
address: gisl-{env}-{region}-ops-audio-watermark-dlq
|
|
736
|
+
description: |
|
|
737
|
+
DLQ for failed audio_watermark operations (per ticket I20).
|
|
738
|
+
Messages land here after 5 failed processing attempts. No
|
|
739
|
+
traffic reaches this queue while audio_watermark is
|
|
740
|
+
`availability: planned` + `required_tier: enterprise`.
|
|
741
|
+
parameters:
|
|
742
|
+
env:
|
|
743
|
+
description: Environment (local, stg, prod)
|
|
744
|
+
region:
|
|
745
|
+
description: AWS region abbreviation (euw1, use1, etc.)
|
|
746
|
+
|
|
747
|
+
# ============================================
|
|
748
|
+
# UPLOAD PROBE (per ticket vBlEurU7 + M2 Epic SrHwuvIl)
|
|
749
|
+
# ============================================
|
|
750
|
+
|
|
751
|
+
uploadProbeRequestsTopic:
|
|
752
|
+
address: gisl-{env}-{region}-upload-probe-requests
|
|
753
|
+
description: |
|
|
754
|
+
SNS topic where the API publishes asynchronous upload-probe
|
|
755
|
+
requests for eager `rich_metadata` enrichment on upload finalize.
|
|
756
|
+
Per ticket [vBlEurU7](https://trello.com/c/vBlEurU7) +
|
|
757
|
+
M2 Epic re-scope ([SrHwuvIl](https://trello.com/c/SrHwuvIl)).
|
|
758
|
+
|
|
759
|
+
The probe Lambda ([rdBHmTfa](https://trello.com/c/rdBHmTfa))
|
|
760
|
+
can be invoked two ways with the same `UploadProbeRequest`
|
|
761
|
+
payload shape:
|
|
762
|
+
|
|
763
|
+
1. **Synchronous AWS Lambda Invoke** (RequestResponse mode) —
|
|
764
|
+
used to back `POST /api/uploads/{id}/probe`. Not modelled
|
|
765
|
+
as an AsyncAPI channel; the request payload + the response
|
|
766
|
+
payload (`UploadProbeResponse` from `openapi/api.yaml`) are
|
|
767
|
+
the contract for that path.
|
|
768
|
+
2. **Asynchronous SNS -> SQS -> Lambda** — used by the upload
|
|
769
|
+
finalize publisher. This topic is the entry point for that
|
|
770
|
+
async branch. The Lambda then publishes the result to the
|
|
771
|
+
`uploadProbeCompletionsQueue` for the API consumer to read.
|
|
772
|
+
|
|
773
|
+
No SNS message attribute filter is applied — the topic has a
|
|
774
|
+
single subscription (`uploadProbeQueue`) and the Lambda accepts
|
|
775
|
+
every probe request published here.
|
|
776
|
+
parameters:
|
|
777
|
+
env:
|
|
778
|
+
description: Environment (local, stg, prod)
|
|
779
|
+
region:
|
|
780
|
+
description: AWS region abbreviation (euw1, use1, etc.)
|
|
781
|
+
messages:
|
|
782
|
+
uploadProbeRequest:
|
|
783
|
+
$ref: '#/components/messages/UploadProbeRequestMessage'
|
|
784
|
+
|
|
785
|
+
uploadProbeQueue:
|
|
786
|
+
address: gisl-{env}-{region}-upload-probe
|
|
787
|
+
description: |
|
|
788
|
+
SQS queue subscribed to the `upload-probe-requests` SNS topic.
|
|
789
|
+
The upload-probe Lambda consumes from this queue.
|
|
790
|
+
|
|
791
|
+
Standard (non-FIFO) — each probe request is independent; no
|
|
792
|
+
ordering guarantees are required across uploads.
|
|
793
|
+
parameters:
|
|
794
|
+
env:
|
|
795
|
+
description: Environment (local, stg, prod)
|
|
796
|
+
region:
|
|
797
|
+
description: AWS region abbreviation (euw1, use1, etc.)
|
|
798
|
+
messages:
|
|
799
|
+
uploadProbeRequest:
|
|
800
|
+
$ref: '#/components/messages/UploadProbeRequestMessage'
|
|
801
|
+
|
|
802
|
+
uploadProbeDlq:
|
|
803
|
+
address: gisl-{env}-{region}-upload-probe-dlq
|
|
804
|
+
description: |
|
|
805
|
+
DLQ for failed upload-probe Lambda invocations from the async
|
|
806
|
+
branch. Messages land here after 5 failed processing attempts.
|
|
807
|
+
The sync `POST /api/uploads/{id}/probe` path does not flow
|
|
808
|
+
through this DLQ — sync errors are surfaced inline via the
|
|
809
|
+
Lambda RequestResponse return value.
|
|
810
|
+
parameters:
|
|
811
|
+
env:
|
|
812
|
+
description: Environment (local, stg, prod)
|
|
813
|
+
region:
|
|
814
|
+
description: AWS region abbreviation (euw1, use1, etc.)
|
|
815
|
+
|
|
816
|
+
uploadProbeCompletionsQueue:
|
|
817
|
+
address: gisl-{env}-{region}-upload-probe-completions
|
|
818
|
+
description: |
|
|
819
|
+
SQS queue where the upload-probe Lambda publishes
|
|
820
|
+
`UploadProbeCompletion` messages on the async branch. The API
|
|
821
|
+
consumer worker reads from this queue and persists
|
|
822
|
+
`rich_metadata` on the upload row.
|
|
823
|
+
|
|
824
|
+
Standard (non-FIFO) — completions are independent; no ordering
|
|
825
|
+
guarantees across uploads. Idempotency is handled by the
|
|
826
|
+
`idempotency_key` field on the message payload (echoed from the
|
|
827
|
+
original request) and by the API consumer's per-upload
|
|
828
|
+
"first-write-wins" persistence path.
|
|
829
|
+
|
|
830
|
+
The sync `POST /api/uploads/{id}/probe` path does not publish
|
|
831
|
+
here — sync results are returned inline via the Lambda
|
|
832
|
+
RequestResponse return value.
|
|
833
|
+
parameters:
|
|
834
|
+
env:
|
|
835
|
+
description: Environment (local, stg, prod)
|
|
836
|
+
region:
|
|
837
|
+
description: AWS region abbreviation (euw1, use1, etc.)
|
|
838
|
+
messages:
|
|
839
|
+
uploadProbeCompletion:
|
|
840
|
+
$ref: '#/components/messages/UploadProbeCompletionMessage'
|
|
841
|
+
|
|
842
|
+
uploadProbeCompletionsDlq:
|
|
843
|
+
address: gisl-{env}-{region}-upload-probe-completions-dlq
|
|
844
|
+
description: |
|
|
845
|
+
DLQ for failed completion-message processing by the API
|
|
846
|
+
consumer worker. Messages land here after 5 failed processing
|
|
847
|
+
attempts (e.g. database persistence failures, malformed
|
|
848
|
+
payloads).
|
|
849
|
+
parameters:
|
|
850
|
+
env:
|
|
851
|
+
description: Environment (local, stg, prod)
|
|
852
|
+
region:
|
|
853
|
+
description: AWS region abbreviation (euw1, use1, etc.)
|
|
854
|
+
|
|
539
855
|
# ============================================
|
|
540
856
|
# NOTIFICATIONS (Lambda -> API)
|
|
541
857
|
# ============================================
|
|
@@ -627,8 +943,9 @@ operations:
|
|
|
627
943
|
Non-compression-branch publisher path. Invoked by the API for any
|
|
628
944
|
operation where `operation_type != compress` — that is, thumbnail
|
|
629
945
|
(including the four sub-type values during the migration window),
|
|
630
|
-
|
|
631
|
-
|
|
946
|
+
image_watermark, text_watermark, merge, archive, convert,
|
|
947
|
+
custom_luma, audio_overlay, audio_watermark. The target SNS
|
|
948
|
+
topic filters subscriptions on `operation_type` alone.
|
|
632
949
|
|
|
633
950
|
**Message attributes set on this branch:** `{operation_type,
|
|
634
951
|
media_group}`, with `media_group` omitted for `archive` (which is
|
|
@@ -653,8 +970,9 @@ operations:
|
|
|
653
970
|
description: |
|
|
654
971
|
The image compression Lambda consumes jobs for image inputs.
|
|
655
972
|
Handles `compress` only. Non-compression image operations
|
|
656
|
-
(thumbnail,
|
|
657
|
-
respective queues on the ops-family under the
|
|
973
|
+
(thumbnail, image_watermark, text_watermark, convert, merge) are
|
|
974
|
+
routed to their respective queues on the ops-family under the
|
|
975
|
+
`operations` topic.
|
|
658
976
|
messages:
|
|
659
977
|
- $ref: '#/channels/jobsImage/messages/jobRequest'
|
|
660
978
|
|
|
@@ -764,17 +1082,36 @@ operations:
|
|
|
764
1082
|
messages:
|
|
765
1083
|
- $ref: '#/channels/opsThumbnailOffice/messages/operationRequest'
|
|
766
1084
|
|
|
767
|
-
|
|
1085
|
+
consumeImageWatermarkOperation:
|
|
768
1086
|
action: receive
|
|
769
1087
|
channel:
|
|
770
|
-
$ref: '#/channels/
|
|
771
|
-
summary: Process
|
|
1088
|
+
$ref: '#/channels/opsImageWatermark'
|
|
1089
|
+
summary: Process image_watermark operation
|
|
772
1090
|
description: |
|
|
773
|
-
The watermark Lambda consumes
|
|
774
|
-
`operation_type=
|
|
775
|
-
|
|
1091
|
+
The operation-image-watermark Lambda consumes image_watermark
|
|
1092
|
+
requests routed by `operation_type=image_watermark`. Multi-input
|
|
1093
|
+
(Path B with role: base + overlay per JobInputV2.role).
|
|
1094
|
+
|
|
1095
|
+
Stable for image bases today; animated GIF (`image_gif` group) and
|
|
1096
|
+
video bases (`video` group) are advertised as `planned` in the
|
|
1097
|
+
schema (I5 — Trello AKZiOXnd) and dispatch returns
|
|
1098
|
+
`feature_not_available` (422) at the API edge until Lambda support
|
|
1099
|
+
ships. Per ADR-0004 + I4-CONS + I5.
|
|
776
1100
|
messages:
|
|
777
|
-
- $ref: '#/channels/
|
|
1101
|
+
- $ref: '#/channels/opsImageWatermark/messages/operationRequest'
|
|
1102
|
+
|
|
1103
|
+
consumeTextWatermarkOperation:
|
|
1104
|
+
action: receive
|
|
1105
|
+
channel:
|
|
1106
|
+
$ref: '#/channels/opsTextWatermark'
|
|
1107
|
+
summary: Process text_watermark operation
|
|
1108
|
+
description: |
|
|
1109
|
+
The operation-text-watermark Lambda consumes text_watermark
|
|
1110
|
+
requests routed by `operation_type=text_watermark`. Single-input;
|
|
1111
|
+
image-only. Renders text via bundled Liberation Sans (SIL OFL),
|
|
1112
|
+
supports `single` and `tiled` watermark_mode. Per ADR-0004 + I4-CONS.
|
|
1113
|
+
messages:
|
|
1114
|
+
- $ref: '#/channels/opsTextWatermark/messages/operationRequest'
|
|
778
1115
|
|
|
779
1116
|
consumeMergeOperation:
|
|
780
1117
|
action: receive
|
|
@@ -783,10 +1120,11 @@ operations:
|
|
|
783
1120
|
summary: Process merge operation
|
|
784
1121
|
description: |
|
|
785
1122
|
The merge Lambda consumes merge requests routed by
|
|
786
|
-
`operation_type=merge`. A single Lambda handles
|
|
787
|
-
types (
|
|
788
|
-
|
|
789
|
-
|
|
1123
|
+
`operation_type=merge`. A single Lambda handles the supported merge
|
|
1124
|
+
output types (animated GIF, video slideshow/concat, audio concat).
|
|
1125
|
+
The `output_type` field on the request determines the encoding
|
|
1126
|
+
path internally. Image collage and PDF concatenation are not
|
|
1127
|
+
supported by the V1 Lambda.
|
|
790
1128
|
messages:
|
|
791
1129
|
- $ref: '#/channels/opsMerge/messages/operationRequest'
|
|
792
1130
|
|
|
@@ -814,6 +1152,59 @@ operations:
|
|
|
814
1152
|
messages:
|
|
815
1153
|
- $ref: '#/channels/opsConvert/messages/operationRequest'
|
|
816
1154
|
|
|
1155
|
+
consumeCustomLumaOperation:
|
|
1156
|
+
action: receive
|
|
1157
|
+
channel:
|
|
1158
|
+
$ref: '#/channels/opsCustomLuma'
|
|
1159
|
+
summary: Process custom_luma operation
|
|
1160
|
+
description: |
|
|
1161
|
+
The `operation-custom-luma` Lambda (cross-repo follow-up — not
|
|
1162
|
+
yet shipped) consumes custom_luma requests routed by
|
|
1163
|
+
`operation_type=custom_luma`. Multi-input (Path B with
|
|
1164
|
+
`role: base` + `role: transition_mask` per `JobInputV2.role`).
|
|
1165
|
+
`availability: planned` + `required_tier: pro`; the API rejects
|
|
1166
|
+
workflow-create with `feature_not_available` (422) until the
|
|
1167
|
+
Lambda ships, so traffic does not reach this channel today.
|
|
1168
|
+
Per ADR-0004 + I29 (Trello EPUE5Vs1).
|
|
1169
|
+
messages:
|
|
1170
|
+
- $ref: '#/channels/opsCustomLuma/messages/operationRequest'
|
|
1171
|
+
|
|
1172
|
+
consumeAudioOverlayOperation:
|
|
1173
|
+
action: receive
|
|
1174
|
+
channel:
|
|
1175
|
+
$ref: '#/channels/opsAudioOverlay'
|
|
1176
|
+
summary: Process audio_overlay operation
|
|
1177
|
+
description: |
|
|
1178
|
+
The `operation-audio-overlay` Lambda (cross-repo follow-up —
|
|
1179
|
+
not yet shipped) consumes audio_overlay requests routed by
|
|
1180
|
+
`operation_type=audio_overlay`. Multi-input (Path B with
|
|
1181
|
+
`role: base` + `role: overlay` per `JobInputV2.role`).
|
|
1182
|
+
Both mime_groups (`audio`, `video`) are `availability: planned`;
|
|
1183
|
+
the API rejects workflow-create with `feature_not_available`
|
|
1184
|
+
(422) until the Lambda ships, so traffic does not reach this
|
|
1185
|
+
channel today.
|
|
1186
|
+
Per ADR-0004 + I19 (Trello Xr3Z4GBF).
|
|
1187
|
+
messages:
|
|
1188
|
+
- $ref: '#/channels/opsAudioOverlay/messages/operationRequest'
|
|
1189
|
+
|
|
1190
|
+
consumeAudioWatermarkOperation:
|
|
1191
|
+
action: receive
|
|
1192
|
+
channel:
|
|
1193
|
+
$ref: '#/channels/opsAudioWatermark'
|
|
1194
|
+
summary: Process audio_watermark operation
|
|
1195
|
+
description: |
|
|
1196
|
+
The `operation-audio-watermark` Lambda (cross-repo follow-up —
|
|
1197
|
+
not yet shipped) consumes audio_watermark requests routed by
|
|
1198
|
+
`operation_type=audio_watermark`. Single-input. Both mime_groups
|
|
1199
|
+
(`audio`, `video`) are `availability: planned` +
|
|
1200
|
+
`required_tier: enterprise`; the API rejects workflow-create
|
|
1201
|
+
with `feature_not_available` (422) until the Lambda ships, plus
|
|
1202
|
+
403 `feature_tier_restricted` for non-enterprise callers, so
|
|
1203
|
+
traffic does not reach this channel today.
|
|
1204
|
+
Per ADR-0004 + I20 (Trello omiCq7Vn).
|
|
1205
|
+
messages:
|
|
1206
|
+
- $ref: '#/channels/opsAudioWatermark/messages/operationRequest'
|
|
1207
|
+
|
|
817
1208
|
# ============================================
|
|
818
1209
|
# NOTIFICATION OPERATIONS
|
|
819
1210
|
# ============================================
|
|
@@ -853,6 +1244,81 @@ operations:
|
|
|
853
1244
|
- $ref: '#/channels/notificationsOperationsQueue/messages/operationProgress'
|
|
854
1245
|
- $ref: '#/channels/notificationsOperationsQueue/messages/operationResult'
|
|
855
1246
|
|
|
1247
|
+
# ============================================
|
|
1248
|
+
# UPLOAD-PROBE OPERATIONS (per ticket vBlEurU7)
|
|
1249
|
+
# ============================================
|
|
1250
|
+
|
|
1251
|
+
publishUploadProbeRequest:
|
|
1252
|
+
action: send
|
|
1253
|
+
channel:
|
|
1254
|
+
$ref: '#/channels/uploadProbeRequestsTopic'
|
|
1255
|
+
summary: Publish an async upload-probe request
|
|
1256
|
+
description: |
|
|
1257
|
+
The API publishes to this topic on the **async branch** —
|
|
1258
|
+
typically from the upload-finalize publisher when eager
|
|
1259
|
+
`rich_metadata` enrichment is configured for the caller's
|
|
1260
|
+
tier / MIME group.
|
|
1261
|
+
|
|
1262
|
+
The `POST /api/uploads/{id}/probe` sync path does **not** use
|
|
1263
|
+
this operation — it invokes the Lambda directly via the AWS
|
|
1264
|
+
Lambda Invoke API (RequestResponse mode). The two paths share
|
|
1265
|
+
the `UploadProbeRequest` payload schema so the Lambda accepts
|
|
1266
|
+
a single request shape regardless of invocation source.
|
|
1267
|
+
messages:
|
|
1268
|
+
- $ref: '#/channels/uploadProbeRequestsTopic/messages/uploadProbeRequest'
|
|
1269
|
+
|
|
1270
|
+
consumeUploadProbeRequest:
|
|
1271
|
+
action: receive
|
|
1272
|
+
channel:
|
|
1273
|
+
$ref: '#/channels/uploadProbeQueue'
|
|
1274
|
+
summary: Consume an upload-probe request (async branch)
|
|
1275
|
+
description: |
|
|
1276
|
+
The upload-probe Lambda consumes from the SQS queue subscribed
|
|
1277
|
+
to the `upload-probe-requests` topic. On success the Lambda
|
|
1278
|
+
publishes an `UploadProbeCompletion` to the completions queue;
|
|
1279
|
+
on failure the Lambda emits a completion with `error_code`
|
|
1280
|
+
populated (so the API consumer can persist the failure mode)
|
|
1281
|
+
before SQS retry / DLQ handling kicks in.
|
|
1282
|
+
|
|
1283
|
+
Sync invocations bypass this operation entirely.
|
|
1284
|
+
messages:
|
|
1285
|
+
- $ref: '#/channels/uploadProbeQueue/messages/uploadProbeRequest'
|
|
1286
|
+
|
|
1287
|
+
publishUploadProbeCompletion:
|
|
1288
|
+
action: send
|
|
1289
|
+
channel:
|
|
1290
|
+
$ref: '#/channels/uploadProbeCompletionsQueue'
|
|
1291
|
+
summary: Publish an upload-probe completion (async branch)
|
|
1292
|
+
description: |
|
|
1293
|
+
The upload-probe Lambda publishes the result of the async
|
|
1294
|
+
branch to this queue. The payload shape is `UploadProbeCompletion`
|
|
1295
|
+
and intentionally carries both the success fields
|
|
1296
|
+
(`probe_status`, `media_metadata`, `processing_class_pre_assignment`)
|
|
1297
|
+
and the failure fields (`error_code`, `error_message`) so the
|
|
1298
|
+
API consumer worker handles both outcomes from a single
|
|
1299
|
+
message shape.
|
|
1300
|
+
|
|
1301
|
+
The sync `POST /api/uploads/{id}/probe` path does not publish
|
|
1302
|
+
here — sync results are returned inline via the Lambda
|
|
1303
|
+
RequestResponse return value as `UploadProbeResponse`
|
|
1304
|
+
(`openapi/api.yaml`).
|
|
1305
|
+
messages:
|
|
1306
|
+
- $ref: '#/channels/uploadProbeCompletionsQueue/messages/uploadProbeCompletion'
|
|
1307
|
+
|
|
1308
|
+
consumeUploadProbeCompletion:
|
|
1309
|
+
action: receive
|
|
1310
|
+
channel:
|
|
1311
|
+
$ref: '#/channels/uploadProbeCompletionsQueue'
|
|
1312
|
+
summary: Consume an upload-probe completion (async branch)
|
|
1313
|
+
description: |
|
|
1314
|
+
The API consumer worker reads completions from this queue and
|
|
1315
|
+
persists `rich_metadata` (and any error state) on the upload
|
|
1316
|
+
row. Idempotency is handled by the `idempotency_key` echoed in
|
|
1317
|
+
the completion payload plus a per-upload "first-write-wins"
|
|
1318
|
+
persistence path on the API side.
|
|
1319
|
+
messages:
|
|
1320
|
+
- $ref: '#/channels/uploadProbeCompletionsQueue/messages/uploadProbeCompletion'
|
|
1321
|
+
|
|
856
1322
|
components:
|
|
857
1323
|
messages:
|
|
858
1324
|
# ============================================
|
|
@@ -933,16 +1399,19 @@ components:
|
|
|
933
1399
|
summary: Request to process a non-compression operation
|
|
934
1400
|
description: |
|
|
935
1401
|
Message sent by the API to request processing of any
|
|
936
|
-
**non-compression** operation (thumbnail,
|
|
937
|
-
archive, convert
|
|
938
|
-
|
|
939
|
-
|
|
1402
|
+
**non-compression** operation (thumbnail, image_watermark,
|
|
1403
|
+
text_watermark, merge, archive, convert, custom_luma,
|
|
1404
|
+
audio_overlay, audio_watermark). Published to the
|
|
1405
|
+
`operations` SNS topic; routed by the single-attribute filter
|
|
1406
|
+
`operation_type` to one of the ops-family queues.
|
|
940
1407
|
|
|
941
1408
|
**SNS Message Attributes:**
|
|
942
1409
|
- `operation_type`: always present. Values: `thumbnail`,
|
|
943
1410
|
`thumbnail_image`, `thumbnail_video`, `thumbnail_document`,
|
|
944
|
-
`thumbnail_office`, `
|
|
945
|
-
|
|
1411
|
+
`thumbnail_office`, `image_watermark`, `text_watermark`,
|
|
1412
|
+
`merge`, `archive`, `convert`, `custom_luma`,
|
|
1413
|
+
`audio_overlay`, `audio_watermark`. Used by SNS as the
|
|
1414
|
+
filter attribute on the `operations` topic.
|
|
946
1415
|
- `media_group`: informational metadata, present for every
|
|
947
1416
|
operation except `archive` (which is media-agnostic). Values:
|
|
948
1417
|
`image`, `video`, `audio`, `document`. **Not** used by SNS as
|
|
@@ -950,12 +1419,23 @@ components:
|
|
|
950
1419
|
log correlation.
|
|
951
1420
|
|
|
952
1421
|
**Input models:**
|
|
953
|
-
- Single-input operations (thumbnail,
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
`
|
|
957
|
-
|
|
958
|
-
|
|
1422
|
+
- Single-input operations (thumbnail, text_watermark, convert,
|
|
1423
|
+
audio_watermark): use `source_bucket` + `source_key`.
|
|
1424
|
+
`file_type` required. For `thumbnail`, the SNS
|
|
1425
|
+
`operation_type` attribute is permitted to carry a per-media
|
|
1426
|
+
sub-type value for routing (see `OperationRequestAttributes`
|
|
1427
|
+
and the migration-window note below); the payload
|
|
1428
|
+
`operation_type` field always remains `thumbnail`.
|
|
1429
|
+
`audio_watermark` is `availability: planned` +
|
|
1430
|
+
`required_tier: enterprise` so workflow-create rejects with
|
|
1431
|
+
422 + 403 today.
|
|
1432
|
+
- Multi-input operations (merge, archive, image_watermark,
|
|
1433
|
+
custom_luma, audio_overlay): use `sources` array. Merge
|
|
1434
|
+
additionally requires `output_type`. image_watermark,
|
|
1435
|
+
custom_luma, and audio_overlay use `role` per
|
|
1436
|
+
`JobInputV2.role`. custom_luma and audio_overlay are
|
|
1437
|
+
`availability: planned` so workflow-create rejects with 422
|
|
1438
|
+
today.
|
|
959
1439
|
|
|
960
1440
|
**Migration window note.** During the thumbnail sub-type
|
|
961
1441
|
migration, both `operation_type=thumbnail` (legacy) and
|
|
@@ -988,14 +1468,14 @@ components:
|
|
|
988
1468
|
fit: "crop"
|
|
989
1469
|
format: "jpg"
|
|
990
1470
|
- name: Thumbnail Image (sub-type)
|
|
991
|
-
summary: Generate a thumbnail for an image using the new thumbnail_image sub-type routing target
|
|
1471
|
+
summary: Generate a thumbnail for an image using the new thumbnail_image sub-type routing target. The SNS attribute `operation_type` carries the sub-type (drives routing); the payload `operation_type` carries the base value (`thumbnail`).
|
|
992
1472
|
headers:
|
|
993
1473
|
operation_type: "thumbnail_image"
|
|
994
1474
|
media_group: "image"
|
|
995
1475
|
payload:
|
|
996
1476
|
job_id: "018f9c42-5d6b-7481-b3df-9fd0a0a5e121"
|
|
997
1477
|
operation_id: "018f9c42-5d6b-7481-b3df-9fd0a0a5e221"
|
|
998
|
-
operation_type: "
|
|
1478
|
+
operation_type: "thumbnail"
|
|
999
1479
|
file_type: "image/png"
|
|
1000
1480
|
source_bucket: "gisl-stg-euw1-input"
|
|
1001
1481
|
source_key: "uploads/018f9c42-kkll/screenshot.png"
|
|
@@ -1006,47 +1486,52 @@ components:
|
|
|
1006
1486
|
height: 512
|
|
1007
1487
|
fit: "max"
|
|
1008
1488
|
format: "webp"
|
|
1009
|
-
- name: Image Watermark (
|
|
1010
|
-
summary: Apply a PNG logo overlay to a JPEG image
|
|
1489
|
+
- name: Image Watermark (file overlay)
|
|
1490
|
+
summary: Apply a PNG logo overlay to a JPEG image (V2 multi-input Path B)
|
|
1011
1491
|
headers:
|
|
1012
|
-
operation_type: "
|
|
1492
|
+
operation_type: "image_watermark"
|
|
1013
1493
|
media_group: "image"
|
|
1014
1494
|
payload:
|
|
1015
1495
|
job_id: "018f9c42-5d6b-7481-b3df-9fd0a0a5e118"
|
|
1016
1496
|
operation_id: "018f9c42-5d6b-7481-b3df-9fd0a0a5e210"
|
|
1017
|
-
operation_type: "
|
|
1497
|
+
operation_type: "image_watermark"
|
|
1018
1498
|
file_type: "image/jpeg"
|
|
1019
|
-
|
|
1020
|
-
|
|
1499
|
+
sources:
|
|
1500
|
+
- role: "base"
|
|
1501
|
+
source_bucket: "gisl-stg-euw1-input"
|
|
1502
|
+
source_key: "uploads/018f9c42-eeff/photo.jpg"
|
|
1503
|
+
- role: "overlay"
|
|
1504
|
+
source_bucket: "gisl-stg-euw1-assets"
|
|
1505
|
+
source_key: "brand/logo.png"
|
|
1021
1506
|
output_bucket: "gisl-stg-euw1-output"
|
|
1022
1507
|
output_key_prefix: "jobs/018f9c42-5d6b-7481-b3df-9fd0a0a5e118/018f9c42-5d6b-7481-b3df-9fd0a0a5e210/"
|
|
1023
1508
|
options:
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
position: "bottom-right"
|
|
1509
|
+
anchor: "bottom_right"
|
|
1510
|
+
margin_x: "20px"
|
|
1511
|
+
margin_y: "20px"
|
|
1028
1512
|
opacity: 0.6
|
|
1029
|
-
|
|
1030
|
-
|
|
1513
|
+
overlay_width: "200px"
|
|
1514
|
+
- name: Text Watermark (tiled)
|
|
1515
|
+
summary: Render a rotated tiled text watermark across a PNG image (V2 single-input)
|
|
1031
1516
|
headers:
|
|
1032
|
-
operation_type: "
|
|
1517
|
+
operation_type: "text_watermark"
|
|
1033
1518
|
media_group: "image"
|
|
1034
1519
|
payload:
|
|
1035
1520
|
job_id: "018f9c42-5d6b-7481-b3df-9fd0a0a5e119"
|
|
1036
1521
|
operation_id: "018f9c42-5d6b-7481-b3df-9fd0a0a5e211"
|
|
1037
|
-
operation_type: "
|
|
1522
|
+
operation_type: "text_watermark"
|
|
1038
1523
|
file_type: "image/png"
|
|
1039
1524
|
source_bucket: "gisl-stg-euw1-input"
|
|
1040
1525
|
source_key: "uploads/018f9c42-gghh/screenshot.png"
|
|
1041
1526
|
output_bucket: "gisl-stg-euw1-output"
|
|
1042
1527
|
output_key_prefix: "jobs/018f9c42-5d6b-7481-b3df-9fd0a0a5e119/018f9c42-5d6b-7481-b3df-9fd0a0a5e211/"
|
|
1043
1528
|
options:
|
|
1044
|
-
watermark_type: "text"
|
|
1045
|
-
watermark_mode: "tiled"
|
|
1046
1529
|
text: "CONFIDENTIAL"
|
|
1047
1530
|
font_size: 64
|
|
1048
1531
|
color: "#FF000080"
|
|
1532
|
+
font_family: "liberation_sans"
|
|
1049
1533
|
rotation: -45
|
|
1534
|
+
watermark_mode: "tiled"
|
|
1050
1535
|
tile_spacing: 120
|
|
1051
1536
|
opacity: 0.4
|
|
1052
1537
|
- name: Image Convert
|
|
@@ -1113,25 +1598,6 @@ components:
|
|
|
1113
1598
|
options:
|
|
1114
1599
|
frame_delay: 100
|
|
1115
1600
|
loop: true
|
|
1116
|
-
- name: PDF Merge
|
|
1117
|
-
summary: Concatenate multiple PDFs into one
|
|
1118
|
-
headers:
|
|
1119
|
-
operation_type: "merge"
|
|
1120
|
-
media_group: "document"
|
|
1121
|
-
payload:
|
|
1122
|
-
job_id: "018f9c42-5d6b-7481-b3df-9fd0a0a5e116"
|
|
1123
|
-
operation_id: "018f9c42-5d6b-7481-b3df-9fd0a0a5e204"
|
|
1124
|
-
operation_type: "merge"
|
|
1125
|
-
file_type: "application/pdf"
|
|
1126
|
-
output_type: "document"
|
|
1127
|
-
sources:
|
|
1128
|
-
- bucket: "gisl-stg-euw1-output"
|
|
1129
|
-
key: "jobs/018f9c42-aaa1/018f9c42-bbb1/chapter1.pdf"
|
|
1130
|
-
- bucket: "gisl-stg-euw1-output"
|
|
1131
|
-
key: "jobs/018f9c42-aaa2/018f9c42-bbb2/chapter2.pdf"
|
|
1132
|
-
output_bucket: "gisl-stg-euw1-output"
|
|
1133
|
-
output_key_prefix: "jobs/018f9c42-5d6b-7481-b3df-9fd0a0a5e116/018f9c42-5d6b-7481-b3df-9fd0a0a5e204/"
|
|
1134
|
-
options: {}
|
|
1135
1601
|
- name: Archive
|
|
1136
1602
|
summary: Bundle multiple files into a ZIP archive (no media_group attribute — archive is media-agnostic)
|
|
1137
1603
|
headers:
|
|
@@ -1216,6 +1682,157 @@ components:
|
|
|
1216
1682
|
# OPERATION RESULT MESSAGE
|
|
1217
1683
|
# ============================================
|
|
1218
1684
|
|
|
1685
|
+
# ============================================
|
|
1686
|
+
# UPLOAD-PROBE MESSAGES (per ticket vBlEurU7)
|
|
1687
|
+
# ============================================
|
|
1688
|
+
|
|
1689
|
+
UploadProbeRequestMessage:
|
|
1690
|
+
name: UploadProbeRequest
|
|
1691
|
+
title: Upload Probe Request
|
|
1692
|
+
summary: Request for the upload-probe Lambda to analyse an uploaded file
|
|
1693
|
+
description: |
|
|
1694
|
+
Request published by the API to the upload-probe Lambda. The
|
|
1695
|
+
same payload shape is also used as the Lambda invoke payload
|
|
1696
|
+
on the synchronous `POST /api/uploads/{id}/probe` path.
|
|
1697
|
+
|
|
1698
|
+
**Invocation paths:**
|
|
1699
|
+
- **Sync (Lambda RequestResponse)** — backs
|
|
1700
|
+
`POST /api/uploads/{id}/probe`. The API Lambda invoker
|
|
1701
|
+
serialises this payload into the Invoke event body and
|
|
1702
|
+
returns the Lambda response (`UploadProbeResponse` from
|
|
1703
|
+
`openapi/api.yaml`) inline.
|
|
1704
|
+
- **Async (SNS -> SQS)** — published to the
|
|
1705
|
+
`upload-probe-requests` topic on upload finalize for eager
|
|
1706
|
+
`rich_metadata` enrichment. The Lambda consumes from the
|
|
1707
|
+
subscribed queue and publishes a completion to the
|
|
1708
|
+
`upload-probe-completions` queue.
|
|
1709
|
+
|
|
1710
|
+
The Lambda differentiates the two paths from the AWS event
|
|
1711
|
+
source (Lambda RequestResponse vs SNS event) — no flag in
|
|
1712
|
+
the payload distinguishes them.
|
|
1713
|
+
contentType: application/json
|
|
1714
|
+
payload:
|
|
1715
|
+
$ref: '#/components/schemas/UploadProbeRequest'
|
|
1716
|
+
examples:
|
|
1717
|
+
- name: Async upload-finalize probe
|
|
1718
|
+
summary: Eager enrichment for a long-form video upload
|
|
1719
|
+
payload:
|
|
1720
|
+
file_id: "019539ab-1111-7000-8000-000000000010"
|
|
1721
|
+
source_bucket: "gisl-stg-euw1-input"
|
|
1722
|
+
source_key: "uploads/019539ab-1111-7000-8000-000000000010/clip.mp4"
|
|
1723
|
+
file_type: "video/mp4"
|
|
1724
|
+
idempotency_key: "upload-finalize:019539ab-1111-7000-8000-000000000010"
|
|
1725
|
+
requested_at: "2026-05-06T13:50:00Z"
|
|
1726
|
+
- name: Sync preflight probe
|
|
1727
|
+
summary: Caller-initiated preflight via POST /api/uploads/{id}/probe
|
|
1728
|
+
payload:
|
|
1729
|
+
file_id: "019539ab-1111-7000-8000-000000000011"
|
|
1730
|
+
source_bucket: "gisl-stg-euw1-input"
|
|
1731
|
+
source_key: "uploads/019539ab-1111-7000-8000-000000000011/clip.mp4"
|
|
1732
|
+
file_type: "video/mp4"
|
|
1733
|
+
idempotency_key: "019539ab-1111-7000-8000-000000000011"
|
|
1734
|
+
requested_at: "2026-05-06T13:50:00Z"
|
|
1735
|
+
|
|
1736
|
+
UploadProbeCompletionMessage:
|
|
1737
|
+
name: UploadProbeCompletion
|
|
1738
|
+
title: Upload Probe Completion
|
|
1739
|
+
summary: Completion notification from the upload-probe Lambda (async branch only)
|
|
1740
|
+
description: |
|
|
1741
|
+
Published by the upload-probe Lambda to the
|
|
1742
|
+
`upload-probe-completions` queue when the async branch
|
|
1743
|
+
finishes. The payload carries either a successful probe
|
|
1744
|
+
result (parity with `UploadProbeResponse` from
|
|
1745
|
+
`openapi/api.yaml`) or a failure envelope (`error_code` +
|
|
1746
|
+
`error_message`).
|
|
1747
|
+
|
|
1748
|
+
**Idempotency.** `idempotency_key` is echoed from the
|
|
1749
|
+
request so the API consumer can deduplicate against its
|
|
1750
|
+
upload row's persisted probe state.
|
|
1751
|
+
|
|
1752
|
+
Sync invocations do not publish here — sync results are
|
|
1753
|
+
returned inline as `UploadProbeResponse`.
|
|
1754
|
+
contentType: application/json
|
|
1755
|
+
payload:
|
|
1756
|
+
$ref: '#/components/schemas/UploadProbeCompletion'
|
|
1757
|
+
examples:
|
|
1758
|
+
- name: Successful probe (long-form video with audio track)
|
|
1759
|
+
summary: Lambda extracted full media metadata for a 4K H.265 video
|
|
1760
|
+
payload:
|
|
1761
|
+
file_id: "019539ab-1111-7000-8000-000000000010"
|
|
1762
|
+
idempotency_key: "upload-finalize:019539ab-1111-7000-8000-000000000010"
|
|
1763
|
+
probe_status: "ok"
|
|
1764
|
+
processing_class_pre_assignment: "long_form"
|
|
1765
|
+
media_metadata:
|
|
1766
|
+
duration_seconds: 5400
|
|
1767
|
+
width: 3840
|
|
1768
|
+
height: 2160
|
|
1769
|
+
codec: "h265"
|
|
1770
|
+
audio_codec: "aac"
|
|
1771
|
+
container: "mp4"
|
|
1772
|
+
fps: 23.976
|
|
1773
|
+
bitrate_bps: 18000000
|
|
1774
|
+
audio_layout: "stereo"
|
|
1775
|
+
channels: 2
|
|
1776
|
+
sample_rate_hz: 48000
|
|
1777
|
+
probed_at: "2026-05-06T13:50:01Z"
|
|
1778
|
+
probed_at: "2026-05-06T13:50:01Z"
|
|
1779
|
+
probe_version: "1.0.0"
|
|
1780
|
+
- name: Successful probe (audio-only)
|
|
1781
|
+
summary: MP3 podcast episode — codec under `codec`, no `audio_codec` field
|
|
1782
|
+
payload:
|
|
1783
|
+
file_id: "019539ab-1111-7000-8000-000000000020"
|
|
1784
|
+
idempotency_key: "upload-finalize:019539ab-1111-7000-8000-000000000020"
|
|
1785
|
+
probe_status: "ok"
|
|
1786
|
+
processing_class_pre_assignment: "short_form"
|
|
1787
|
+
media_metadata:
|
|
1788
|
+
duration_seconds: 2700
|
|
1789
|
+
codec: "mp3"
|
|
1790
|
+
container: "mp3"
|
|
1791
|
+
bitrate_bps: 192000
|
|
1792
|
+
audio_layout: "stereo"
|
|
1793
|
+
channels: 2
|
|
1794
|
+
sample_rate_hz: 44100
|
|
1795
|
+
probed_at: "2026-05-06T13:50:01Z"
|
|
1796
|
+
probed_at: "2026-05-06T13:50:01Z"
|
|
1797
|
+
probe_version: "1.0.0"
|
|
1798
|
+
- name: Successful probe (document)
|
|
1799
|
+
summary: PDF — `page_count` + `dpi` populated, video/audio fields omitted
|
|
1800
|
+
payload:
|
|
1801
|
+
file_id: "019539ab-1111-7000-8000-000000000021"
|
|
1802
|
+
idempotency_key: "upload-finalize:019539ab-1111-7000-8000-000000000021"
|
|
1803
|
+
probe_status: "ok"
|
|
1804
|
+
processing_class_pre_assignment: "short_form"
|
|
1805
|
+
media_metadata:
|
|
1806
|
+
container: "pdf"
|
|
1807
|
+
page_count: 42
|
|
1808
|
+
dpi: 300
|
|
1809
|
+
probed_at: "2026-05-06T13:50:01Z"
|
|
1810
|
+
probed_at: "2026-05-06T13:50:01Z"
|
|
1811
|
+
probe_version: "1.0.0"
|
|
1812
|
+
- name: Probe surfaced unsupported codec
|
|
1813
|
+
summary: Container readable; codec not in supported set
|
|
1814
|
+
payload:
|
|
1815
|
+
file_id: "019539ab-1111-7000-8000-000000000012"
|
|
1816
|
+
idempotency_key: "upload-finalize:019539ab-1111-7000-8000-000000000012"
|
|
1817
|
+
probe_status: "unsupported_codec"
|
|
1818
|
+
processing_class_pre_assignment: "blocked"
|
|
1819
|
+
media_metadata:
|
|
1820
|
+
duration_seconds: 600
|
|
1821
|
+
codec: "prores"
|
|
1822
|
+
container: "mov"
|
|
1823
|
+
probed_at: "2026-05-06T13:50:01Z"
|
|
1824
|
+
probed_at: "2026-05-06T13:50:01Z"
|
|
1825
|
+
probe_version: "1.0.0"
|
|
1826
|
+
- name: Probe failed (Lambda-side error)
|
|
1827
|
+
summary: S3 download failed; probe could not run
|
|
1828
|
+
payload:
|
|
1829
|
+
file_id: "019539ab-1111-7000-8000-000000000013"
|
|
1830
|
+
idempotency_key: "upload-finalize:019539ab-1111-7000-8000-000000000013"
|
|
1831
|
+
error_code: "s3_download_failed"
|
|
1832
|
+
error_message: "Failed to download source file from S3"
|
|
1833
|
+
probed_at: "2026-05-06T13:50:01Z"
|
|
1834
|
+
probe_version: "1.0.0"
|
|
1835
|
+
|
|
1219
1836
|
OperationResultMessage:
|
|
1220
1837
|
name: OperationResult
|
|
1221
1838
|
title: Operation Result
|
|
@@ -1290,8 +1907,148 @@ components:
|
|
|
1290
1907
|
error_message: "Failed to download source file from S3"
|
|
1291
1908
|
is_retryable: true
|
|
1292
1909
|
last_progress: 0
|
|
1910
|
+
- name: Successful Multi-Output Convert (PDF to PNG, 3 pages)
|
|
1911
|
+
summary: Convert PDF->image fan-out result per ADR-0009
|
|
1912
|
+
payload:
|
|
1913
|
+
job_id: "018f9c42-5d6b-7481-b3df-9fd0a0a5e115"
|
|
1914
|
+
operation_id: "018f9c42-5d6b-7481-b3df-9fd0a0a5e203"
|
|
1915
|
+
operation_type: "convert"
|
|
1916
|
+
status: "completed"
|
|
1917
|
+
output_bucket: "gisl-stg-euw1-output"
|
|
1918
|
+
total_output_size_bytes: 786432
|
|
1919
|
+
outputs:
|
|
1920
|
+
- output_key: "jobs/018f9c42-5d6b/018f9c42-5d6b-e203/page-001.png"
|
|
1921
|
+
output_size_bytes: 262144
|
|
1922
|
+
page_index: 1
|
|
1923
|
+
- output_key: "jobs/018f9c42-5d6b/018f9c42-5d6b-e203/page-002.png"
|
|
1924
|
+
output_size_bytes: 262144
|
|
1925
|
+
page_index: 2
|
|
1926
|
+
- output_key: "jobs/018f9c42-5d6b/018f9c42-5d6b-e203/page-003.png"
|
|
1927
|
+
output_size_bytes: 262144
|
|
1928
|
+
page_index: 3
|
|
1929
|
+
metrics:
|
|
1930
|
+
input_count: 1
|
|
1931
|
+
output_size_bytes: 786432
|
|
1932
|
+
duration_ms: 2300
|
|
1933
|
+
- name: Failed Multi-Output Convert (page 2 of 3 corrupted)
|
|
1934
|
+
summary: |
|
|
1935
|
+
Multi-output operation failed mid-stream per ADR-0009 §D3 (all-or-nothing
|
|
1936
|
+
failure). Lambda short-circuited on page 2; page 1 was uploaded before
|
|
1937
|
+
the failure, listed in outputs[] as informational data only — consumers
|
|
1938
|
+
MUST NOT treat them as usable on failure.
|
|
1939
|
+
payload:
|
|
1940
|
+
job_id: "018f9c42-5d6b-7481-b3df-9fd0a0a5e115"
|
|
1941
|
+
operation_id: "018f9c42-5d6b-7481-b3df-9fd0a0a5e203"
|
|
1942
|
+
operation_type: "convert"
|
|
1943
|
+
status: "failed"
|
|
1944
|
+
error_code: "processing_failed"
|
|
1945
|
+
error_message: "pdftocairo failed on page 2: invalid page tree node"
|
|
1946
|
+
is_retryable: false
|
|
1947
|
+
last_progress: 50
|
|
1948
|
+
outputs:
|
|
1949
|
+
- output_key: "jobs/018f9c42-5d6b/018f9c42-5d6b-e203/page-001.png"
|
|
1950
|
+
output_size_bytes: 262144
|
|
1951
|
+
page_index: 1
|
|
1293
1952
|
|
|
1294
1953
|
schemas:
|
|
1954
|
+
# ============================================
|
|
1955
|
+
# AVAILABILITY METADATA (decorative)
|
|
1956
|
+
# ============================================
|
|
1957
|
+
|
|
1958
|
+
AvailabilityValue:
|
|
1959
|
+
type: string
|
|
1960
|
+
description: |
|
|
1961
|
+
Availability level for an operation, mime_group, option, or
|
|
1962
|
+
per-enum-value entry per ADR-0001 §1.3. Mirrors the
|
|
1963
|
+
`AvailabilityValue` schema in `openapi/api.yaml` so SDK
|
|
1964
|
+
generators that consume both specs emit a single typed binding.
|
|
1965
|
+
|
|
1966
|
+
Used as the value of decorative `x-availability` extensions in
|
|
1967
|
+
this spec, and as the typed schema future tickets (I17
|
|
1968
|
+
`per_value_availability` primitive; I27 phased progress states)
|
|
1969
|
+
reference for availability metadata on event payloads.
|
|
1970
|
+
|
|
1971
|
+
Per ADR-0001 §1.4: when `availability` is absent, the implicit
|
|
1972
|
+
value is `stable` for consumers. `stable_pending_audit` is
|
|
1973
|
+
internal CI accounting only and never surfaces.
|
|
1974
|
+
|
|
1975
|
+
See `schemas/FORMAT.md` §Availability Taxonomy for full rules.
|
|
1976
|
+
enum:
|
|
1977
|
+
- stable
|
|
1978
|
+
- beta
|
|
1979
|
+
- experimental
|
|
1980
|
+
- planned
|
|
1981
|
+
- deprecated
|
|
1982
|
+
|
|
1983
|
+
PerValueAvailabilityEntry:
|
|
1984
|
+
type: object
|
|
1985
|
+
description: |
|
|
1986
|
+
Single per-enum-value availability entry. Mirrors
|
|
1987
|
+
`PerValueAvailabilityEntry` in `openapi/api.yaml` so SDK
|
|
1988
|
+
generators consuming both specs emit a single typed binding.
|
|
1989
|
+
|
|
1990
|
+
AsyncAPI consumers: this primitive is the canonical mechanism
|
|
1991
|
+
for tagging individual enum values at different availability
|
|
1992
|
+
levels — see `schemas/operations/merge.yaml` `transition`
|
|
1993
|
+
(per ticket I16-CONS) and `audio_watermark.method` /
|
|
1994
|
+
`audio_overlay.mode` for shipped consumers. The
|
|
1995
|
+
`ProgressStatus` enum (probing / decoding / encoding values
|
|
1996
|
+
landed via ticket I27) deliberately does NOT use
|
|
1997
|
+
`per_value_availability` — those phase statuses are
|
|
1998
|
+
long-form-operation conditional rather than caller-facing
|
|
1999
|
+
feature gates, and their visibility is controlled by which
|
|
2000
|
+
operations emit them rather than by per-value availability
|
|
2001
|
+
tags.
|
|
2002
|
+
|
|
2003
|
+
See `schemas/FORMAT.md` §Availability Taxonomy for full rules.
|
|
2004
|
+
required:
|
|
2005
|
+
- availability
|
|
2006
|
+
properties:
|
|
2007
|
+
availability:
|
|
2008
|
+
$ref: '#/components/schemas/AvailabilityValue'
|
|
2009
|
+
required_tier:
|
|
2010
|
+
description: Tier required to use this enum value. Optional.
|
|
2011
|
+
type: string
|
|
2012
|
+
enum:
|
|
2013
|
+
- free
|
|
2014
|
+
- pro
|
|
2015
|
+
- enterprise
|
|
2016
|
+
eta:
|
|
2017
|
+
type: string
|
|
2018
|
+
description: |
|
|
2019
|
+
ISO-8601 date or quarter (`2026-Q3`) when this value is
|
|
2020
|
+
expected to ship. Only meaningful for `availability: planned`.
|
|
2021
|
+
documentation_url:
|
|
2022
|
+
type: string
|
|
2023
|
+
format: uri
|
|
2024
|
+
sunset:
|
|
2025
|
+
type: string
|
|
2026
|
+
format: date
|
|
2027
|
+
|
|
2028
|
+
PerValueAvailability:
|
|
2029
|
+
type: object
|
|
2030
|
+
description: |
|
|
2031
|
+
Map of enum-value → `PerValueAvailabilityEntry`. Mirrors the
|
|
2032
|
+
OpenAPI version. Keys MUST be a subset of the option / status
|
|
2033
|
+
enum's `values[]` (or AsyncAPI message field's `enum`) array.
|
|
2034
|
+
additionalProperties:
|
|
2035
|
+
$ref: '#/components/schemas/PerValueAvailabilityEntry'
|
|
2036
|
+
|
|
2037
|
+
PerMimeAvailability:
|
|
2038
|
+
type: object
|
|
2039
|
+
description: |
|
|
2040
|
+
Map of MIME-type → `PerValueAvailabilityEntry`. Mirrors the
|
|
2041
|
+
OpenAPI `PerMimeAvailability` schema so SDK generators
|
|
2042
|
+
consuming both specs emit a single typed binding.
|
|
2043
|
+
|
|
2044
|
+
Keys MUST be a subset of the parent
|
|
2045
|
+
`mime_groups.<group>.mimes` array (CI-checked by
|
|
2046
|
+
`scripts/check-per-mime-availability.py`). Absent keys default
|
|
2047
|
+
to `availability: stable` per ADR-0001 §1.4. Per ticket
|
|
2048
|
+
[`YXYOo6gg`](https://trello.com/c/YXYOo6gg).
|
|
2049
|
+
additionalProperties:
|
|
2050
|
+
$ref: '#/components/schemas/PerValueAvailabilityEntry'
|
|
2051
|
+
|
|
1295
2052
|
# ============================================
|
|
1296
2053
|
# FIFO MESSAGE HEADERS
|
|
1297
2054
|
# ============================================
|
|
@@ -1374,8 +2131,35 @@ components:
|
|
|
1374
2131
|
- `operation_type` is always present.
|
|
1375
2132
|
- `media_group` is required iff `operation_type != archive`.
|
|
1376
2133
|
Archive is explicitly omitted because it is media-agnostic.
|
|
1377
|
-
- For `operation_type
|
|
1378
|
-
`image` (
|
|
2134
|
+
- For `operation_type = text_watermark`, `media_group` must
|
|
2135
|
+
equal `image` (text_watermark is image-only).
|
|
2136
|
+
- For `operation_type = custom_luma`, `media_group` must
|
|
2137
|
+
equal `video` (custom_luma applies a luma matte to a video
|
|
2138
|
+
base; the operation is `availability: planned` per
|
|
2139
|
+
[I29](https://trello.com/c/EPUE5Vs1) so this constraint is
|
|
2140
|
+
contract-defined but not exercised today).
|
|
2141
|
+
- For `operation_type = audio_overlay`, `media_group` must
|
|
2142
|
+
equal `audio` or `video` (audio_overlay supports both —
|
|
2143
|
+
mixing into an audio track or into a video's audio track).
|
|
2144
|
+
Both mime_groups are `availability: planned` per
|
|
2145
|
+
[I19](https://trello.com/c/Xr3Z4GBF), so this constraint is
|
|
2146
|
+
contract-defined but not exercised today.
|
|
2147
|
+
- For `operation_type = audio_watermark`, `media_group` must
|
|
2148
|
+
equal `audio` or `video` (audio_watermark supports both —
|
|
2149
|
+
embedding into an audio asset or into a video's audio
|
|
2150
|
+
track). Both mime_groups are `availability: planned` +
|
|
2151
|
+
`required_tier: enterprise` per
|
|
2152
|
+
[I20](https://trello.com/c/omiCq7Vn), so this constraint is
|
|
2153
|
+
contract-defined but not exercised today.
|
|
2154
|
+
- For `operation_type = image_watermark`, `media_group` must
|
|
2155
|
+
equal `image` while only the stable `image` mime_group is
|
|
2156
|
+
dispatchable. The schema declares `image_gif` and `video`
|
|
2157
|
+
mime_groups at `availability: planned` (I5 — Trello AKZiOXnd);
|
|
2158
|
+
when those flip to `stable`, this constraint widens to
|
|
2159
|
+
`{image, video}` (animated GIF carries `media_group=image`).
|
|
2160
|
+
Until then the API rejects non-image bases at workflow-create
|
|
2161
|
+
time with `feature_not_available` (422), so SNS-attribute
|
|
2162
|
+
values stay constrained to `image`.
|
|
1379
2163
|
- For the four thumbnail sub-types, `media_group` is constrained
|
|
1380
2164
|
to the matching media:
|
|
1381
2165
|
- `thumbnail_image` -> `image`
|
|
@@ -1398,10 +2182,14 @@ components:
|
|
|
1398
2182
|
- thumbnail_video
|
|
1399
2183
|
- thumbnail_document
|
|
1400
2184
|
- thumbnail_office
|
|
1401
|
-
-
|
|
2185
|
+
- image_watermark
|
|
2186
|
+
- text_watermark
|
|
1402
2187
|
- merge
|
|
1403
2188
|
- archive
|
|
1404
2189
|
- convert
|
|
2190
|
+
- custom_luma
|
|
2191
|
+
- audio_overlay
|
|
2192
|
+
- audio_watermark
|
|
1405
2193
|
media_group:
|
|
1406
2194
|
type: string
|
|
1407
2195
|
description: |
|
|
@@ -1429,11 +2217,43 @@ components:
|
|
|
1429
2217
|
- if:
|
|
1430
2218
|
properties:
|
|
1431
2219
|
operation_type:
|
|
1432
|
-
const:
|
|
2220
|
+
const: image_watermark
|
|
2221
|
+
then:
|
|
2222
|
+
properties:
|
|
2223
|
+
media_group:
|
|
2224
|
+
const: image
|
|
2225
|
+
- if:
|
|
2226
|
+
properties:
|
|
2227
|
+
operation_type:
|
|
2228
|
+
const: text_watermark
|
|
1433
2229
|
then:
|
|
1434
2230
|
properties:
|
|
1435
2231
|
media_group:
|
|
1436
2232
|
const: image
|
|
2233
|
+
- if:
|
|
2234
|
+
properties:
|
|
2235
|
+
operation_type:
|
|
2236
|
+
const: custom_luma
|
|
2237
|
+
then:
|
|
2238
|
+
properties:
|
|
2239
|
+
media_group:
|
|
2240
|
+
const: video
|
|
2241
|
+
- if:
|
|
2242
|
+
properties:
|
|
2243
|
+
operation_type:
|
|
2244
|
+
const: audio_overlay
|
|
2245
|
+
then:
|
|
2246
|
+
properties:
|
|
2247
|
+
media_group:
|
|
2248
|
+
enum: [audio, video]
|
|
2249
|
+
- if:
|
|
2250
|
+
properties:
|
|
2251
|
+
operation_type:
|
|
2252
|
+
const: audio_watermark
|
|
2253
|
+
then:
|
|
2254
|
+
properties:
|
|
2255
|
+
media_group:
|
|
2256
|
+
enum: [audio, video]
|
|
1437
2257
|
- if:
|
|
1438
2258
|
properties:
|
|
1439
2259
|
operation_type:
|
|
@@ -1479,15 +2299,17 @@ components:
|
|
|
1479
2299
|
`OperationRequestMessage` (non-compression branch). Published by
|
|
1480
2300
|
API to SNS, consumed by Lambda from SQS.
|
|
1481
2301
|
|
|
1482
|
-
**Single-input operations** (compress, thumbnail,
|
|
1483
|
-
thumbnail_video, thumbnail_document, thumbnail_office, watermark,
|
|
2302
|
+
**Single-input operations** (compress, thumbnail, text_watermark,
|
|
1484
2303
|
convert): use `source_bucket` + `source_key` for the input file.
|
|
1485
2304
|
`file_type` is required.
|
|
1486
2305
|
|
|
1487
|
-
**Multi-input operations** (merge, archive
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
2306
|
+
**Multi-input operations** (merge, archive, image_watermark,
|
|
2307
|
+
custom_luma, audio_overlay): use `sources` array. Each entry
|
|
2308
|
+
has `bucket` + `key`. Merge entries may include per-input
|
|
2309
|
+
overrides (e.g. transition type). Merge also requires
|
|
2310
|
+
`output_type`. custom_luma and audio_overlay are
|
|
2311
|
+
`availability: planned` so workflow-create rejects with 422
|
|
2312
|
+
today; the wire shape is contract-defined.
|
|
1491
2313
|
|
|
1492
2314
|
Note: `media_group` is **not** a field in this payload. It exists
|
|
1493
2315
|
only as an SNS MessageAttribute on the non-compression branch; on
|
|
@@ -1506,12 +2328,9 @@ components:
|
|
|
1506
2328
|
enum:
|
|
1507
2329
|
- compress
|
|
1508
2330
|
- thumbnail
|
|
1509
|
-
-
|
|
1510
|
-
- thumbnail_video
|
|
1511
|
-
- thumbnail_document
|
|
1512
|
-
- thumbnail_office
|
|
1513
|
-
- watermark
|
|
2331
|
+
- text_watermark
|
|
1514
2332
|
- convert
|
|
2333
|
+
- audio_watermark
|
|
1515
2334
|
then:
|
|
1516
2335
|
required:
|
|
1517
2336
|
- file_type
|
|
@@ -1520,7 +2339,7 @@ components:
|
|
|
1520
2339
|
- if:
|
|
1521
2340
|
properties:
|
|
1522
2341
|
operation_type:
|
|
1523
|
-
enum: [merge, archive]
|
|
2342
|
+
enum: [merge, archive, image_watermark, custom_luma, audio_overlay]
|
|
1524
2343
|
then:
|
|
1525
2344
|
required:
|
|
1526
2345
|
- sources
|
|
@@ -1584,9 +2403,14 @@ components:
|
|
|
1584
2403
|
sources:
|
|
1585
2404
|
type: array
|
|
1586
2405
|
description: |
|
|
1587
|
-
Input files for multi-input operations (merge, archive
|
|
1588
|
-
|
|
1589
|
-
|
|
2406
|
+
Input files for multi-input operations (merge, archive,
|
|
2407
|
+
image_watermark, custom_luma, audio_overlay). Each entry
|
|
2408
|
+
specifies an S3 location. Order matters for merge
|
|
2409
|
+
(concatenation order). Per-input overrides (e.g.
|
|
2410
|
+
transition) can be inlined on each entry.
|
|
2411
|
+
Role-based multi-input operations (image_watermark,
|
|
2412
|
+
custom_luma, audio_overlay) require a `role` discriminator
|
|
2413
|
+
on each entry — see `SourceEntry.role`.
|
|
1590
2414
|
items:
|
|
1591
2415
|
$ref: '#/components/schemas/SourceEntry'
|
|
1592
2416
|
minItems: 2
|
|
@@ -1633,8 +2457,11 @@ components:
|
|
|
1633
2457
|
SourceEntry:
|
|
1634
2458
|
type: object
|
|
1635
2459
|
description: |
|
|
1636
|
-
A single source file for multi-input operations (merge,
|
|
1637
|
-
|
|
2460
|
+
A single source file for multi-input operations (merge,
|
|
2461
|
+
archive, image_watermark, custom_luma, audio_overlay).
|
|
2462
|
+
Provides the S3 location, optional per-input overrides, and
|
|
2463
|
+
the `role` discriminator for role-based multi-input
|
|
2464
|
+
operations.
|
|
1638
2465
|
required:
|
|
1639
2466
|
- bucket
|
|
1640
2467
|
- key
|
|
@@ -1647,18 +2474,16 @@ components:
|
|
|
1647
2474
|
type: string
|
|
1648
2475
|
description: S3 key of the source file
|
|
1649
2476
|
example: "jobs/018f9c42-aaa1/018f9c42-bbb1/intro.mp4"
|
|
2477
|
+
role:
|
|
2478
|
+
# Named schema preserves the per-operation role rules in its
|
|
2479
|
+
# description; lifted from inline per ticket QokFw8VR.
|
|
2480
|
+
$ref: '#/components/schemas/JobInputRole'
|
|
1650
2481
|
transition:
|
|
1651
2482
|
type: string
|
|
1652
2483
|
description: |
|
|
1653
2484
|
Per-input transition override for video merge.
|
|
1654
2485
|
Overrides the global transition option for the join point before this input.
|
|
1655
2486
|
example: "none"
|
|
1656
|
-
page_range:
|
|
1657
|
-
type: string
|
|
1658
|
-
description: |
|
|
1659
|
-
Page range for PDF merge. Selects specific pages from this input.
|
|
1660
|
-
Format: "1-5", "1,3,5-10". Omit for all pages.
|
|
1661
|
-
example: "1-5"
|
|
1662
2487
|
|
|
1663
2488
|
# ============================================
|
|
1664
2489
|
# OPERATION PROGRESS SCHEMA
|
|
@@ -1704,6 +2529,30 @@ components:
|
|
|
1704
2529
|
type: string
|
|
1705
2530
|
description: Human-readable description of current processing stage
|
|
1706
2531
|
example: "Compressing image"
|
|
2532
|
+
phase_input_index:
|
|
2533
|
+
type: integer
|
|
2534
|
+
minimum: 1
|
|
2535
|
+
description: |
|
|
2536
|
+
1-based index of the input currently being processed in
|
|
2537
|
+
this phase. Emitted only when `status` is `probing` or
|
|
2538
|
+
`decoding` (and optionally `encoding` for multi-output
|
|
2539
|
+
operations) to give callers visibility into long-form
|
|
2540
|
+
jobs that internally process inputs sequentially.
|
|
2541
|
+
Frontend renders "probing input 2/4" / "decoding input
|
|
2542
|
+
3/4" without callers having to decompose into multiple
|
|
2543
|
+
jobs. Per ticket I27 (Trello 1R3K3bsG) + plan v5 §F8.3.
|
|
2544
|
+
example: 2
|
|
2545
|
+
phase_total_inputs:
|
|
2546
|
+
type: integer
|
|
2547
|
+
minimum: 1
|
|
2548
|
+
description: |
|
|
2549
|
+
Total number of inputs expected in this phase. Pairs with
|
|
2550
|
+
`phase_input_index`. For single-input operations (most
|
|
2551
|
+
ops) `phase_total_inputs: 1` and `phase_input_index: 1`
|
|
2552
|
+
during the relevant phase. For multi-input merge,
|
|
2553
|
+
archive, image_watermark, custom_luma, and audio_overlay,
|
|
2554
|
+
this matches the inputs[] count. Per ticket I27.
|
|
2555
|
+
example: 4
|
|
1707
2556
|
|
|
1708
2557
|
# ============================================
|
|
1709
2558
|
# OPERATION RESULT SCHEMA
|
|
@@ -1717,25 +2566,81 @@ components:
|
|
|
1717
2566
|
|
|
1718
2567
|
**Important**: This message MUST always be sent, whether the operation
|
|
1719
2568
|
succeeds or fails. It is the definitive signal that processing is complete.
|
|
2569
|
+
|
|
2570
|
+
## Single-output vs multi-output completion
|
|
2571
|
+
|
|
2572
|
+
Per [ADR-0009](../docs/decisions/0009-multi-output-result-envelope.md),
|
|
2573
|
+
successful completion uses one of two mutually-exclusive shapes:
|
|
2574
|
+
|
|
2575
|
+
- **Single-output** (compress, watermark, merge, archive, convert
|
|
2576
|
+
single-output, thumbnail): top-level `output_key` + `output_size_bytes`
|
|
2577
|
+
are present; `outputs[]` is absent.
|
|
2578
|
+
- **Multi-output** (convert PDF->image; future fan-out operations):
|
|
2579
|
+
`outputs[]` + `total_output_size_bytes` are present; top-level
|
|
2580
|
+
`output_key` / `output_size_bytes` are absent. Consumers MUST use
|
|
2581
|
+
`outputs.length` (or its language equivalent) for the count; per
|
|
2582
|
+
ADR-0009 §D4 a denormalised `output_count` field was deliberately
|
|
2583
|
+
rejected.
|
|
2584
|
+
|
|
2585
|
+
`output_bucket` is shared across both shapes — all outputs in a
|
|
2586
|
+
multi-output operation live in the same bucket.
|
|
2587
|
+
|
|
2588
|
+
Failure (`status: failed`) is unified across both shapes: one
|
|
2589
|
+
`error_code` + `error_message` + `is_retryable` at the top level; no
|
|
2590
|
+
per-output error array (all-or-nothing failure per ADR-0009 §D3).
|
|
2591
|
+
`outputs[]` MAY be present on failure as informational data showing
|
|
2592
|
+
which outputs completed before the failing one; consumers MUST NOT
|
|
2593
|
+
treat them as usable.
|
|
1720
2594
|
required:
|
|
1721
2595
|
- job_id
|
|
1722
2596
|
- operation_id
|
|
1723
2597
|
- operation_type
|
|
1724
2598
|
- status
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
2599
|
+
oneOf:
|
|
2600
|
+
- title: SingleOutputCompletion
|
|
2601
|
+
description: |
|
|
2602
|
+
Legacy single-output completion. Used by compress, watermark,
|
|
2603
|
+
merge, archive, convert single-output, and thumbnail operations.
|
|
2604
|
+
properties:
|
|
2605
|
+
status:
|
|
2606
|
+
const: completed
|
|
2607
|
+
required:
|
|
2608
|
+
- output_bucket
|
|
2609
|
+
- output_key
|
|
2610
|
+
- output_size_bytes
|
|
2611
|
+
not:
|
|
2612
|
+
anyOf:
|
|
2613
|
+
- required: [outputs]
|
|
2614
|
+
- required: [output_count]
|
|
2615
|
+
- required: [total_output_size_bytes]
|
|
2616
|
+
- title: MultiOutputCompletion
|
|
2617
|
+
description: |
|
|
2618
|
+
Multi-output completion. Used by convert PDF->image and future
|
|
2619
|
+
fan-out operations. Per ADR-0009.
|
|
2620
|
+
properties:
|
|
2621
|
+
status:
|
|
2622
|
+
const: completed
|
|
2623
|
+
required:
|
|
2624
|
+
- output_bucket
|
|
2625
|
+
- outputs
|
|
2626
|
+
- total_output_size_bytes
|
|
2627
|
+
not:
|
|
2628
|
+
anyOf:
|
|
2629
|
+
- required: [output_key]
|
|
2630
|
+
- required: [output_size_bytes]
|
|
2631
|
+
- title: Failure
|
|
2632
|
+
description: |
|
|
2633
|
+
Operation failed (single- or multi-output). One top-level error
|
|
2634
|
+
envelope per ADR-0009 §D3 (all-or-nothing failure). `outputs[]`
|
|
2635
|
+
MAY be present with partial results as informational data; do
|
|
2636
|
+
not consume.
|
|
2637
|
+
properties:
|
|
2638
|
+
status:
|
|
2639
|
+
const: failed
|
|
2640
|
+
required:
|
|
2641
|
+
- error_code
|
|
2642
|
+
- error_message
|
|
2643
|
+
- is_retryable
|
|
1739
2644
|
properties:
|
|
1740
2645
|
job_id:
|
|
1741
2646
|
type: string
|
|
@@ -1752,20 +2657,75 @@ components:
|
|
|
1752
2657
|
status:
|
|
1753
2658
|
$ref: '#/components/schemas/ResultStatus'
|
|
1754
2659
|
|
|
1755
|
-
#
|
|
2660
|
+
# Shared success field (both single- and multi-output)
|
|
1756
2661
|
output_bucket:
|
|
1757
2662
|
type: string
|
|
1758
|
-
description:
|
|
2663
|
+
description: |
|
|
2664
|
+
S3 bucket where output file(s) are stored. Present on completion
|
|
2665
|
+
for both single- and multi-output operations; all outputs in a
|
|
2666
|
+
multi-output operation share this bucket. Absent on failure.
|
|
1759
2667
|
example: "gisl-stg-euw1-output"
|
|
2668
|
+
|
|
2669
|
+
# Single-output success fields (legacy; per ADR-0009 SingleOutputCompletion)
|
|
1760
2670
|
output_key:
|
|
1761
2671
|
type: string
|
|
1762
|
-
description:
|
|
2672
|
+
description: |
|
|
2673
|
+
S3 key of the output file. Single-output completion only — mutually
|
|
2674
|
+
exclusive with `outputs[]`. Absent for multi-output operations and
|
|
2675
|
+
on failure.
|
|
1763
2676
|
example: "jobs/018f9c42-5d6b/018f9c42-5d6b-e200/photo_compressed.png"
|
|
1764
2677
|
output_size_bytes:
|
|
1765
2678
|
type: integer
|
|
1766
2679
|
format: int64
|
|
1767
|
-
description:
|
|
2680
|
+
description: |
|
|
2681
|
+
Output file size in bytes. Single-output completion only — mutually
|
|
2682
|
+
exclusive with `outputs[]`. Absent for multi-output operations and
|
|
2683
|
+
on failure.
|
|
1768
2684
|
example: 2097152
|
|
2685
|
+
|
|
2686
|
+
# Multi-output success fields (per ADR-0009 MultiOutputCompletion)
|
|
2687
|
+
outputs:
|
|
2688
|
+
type: array
|
|
2689
|
+
minItems: 1
|
|
2690
|
+
maxItems: 200
|
|
2691
|
+
description: |
|
|
2692
|
+
Per-output details for multi-output operations (e.g. convert
|
|
2693
|
+
PDF->image emits one entry per page). Mutually exclusive with
|
|
2694
|
+
top-level `output_key` / `output_size_bytes` on completion. MAY
|
|
2695
|
+
be present on failure as informational data showing partial
|
|
2696
|
+
results; consumers MUST NOT treat those as usable. See ADR-0009.
|
|
2697
|
+
|
|
2698
|
+
**`maxItems: 200`** is a worst-case transport-layer defence
|
|
2699
|
+
against SQS/SNS's 256 KiB payload cap. Worst-case per-entry size
|
|
2700
|
+
is ~1080 bytes (1024-char `output_key` at the S3 hard limit + ~55
|
|
2701
|
+
bytes JSON envelope per entry); 200 entries × 1080 bytes ≈ 216
|
|
2702
|
+
KB, leaving ~40 KB headroom for the outer message envelope
|
|
2703
|
+
(`job_id`, `operation_id`, `metrics`, `total_output_size_bytes`,
|
|
2704
|
+
etc.). Typical Lambda-generated keys are ~110 chars so the
|
|
2705
|
+
realistic per-message size stays well under the cap; this bound
|
|
2706
|
+
defends against the worst case, not the typical case.
|
|
2707
|
+
|
|
2708
|
+
Operations that could theoretically exceed 200 outputs from one
|
|
2709
|
+
logical operation (e.g. convert PDF->image on a >200-page PDF)
|
|
2710
|
+
MUST enforce a corresponding upper bound on the input side
|
|
2711
|
+
(per-operation page-range / count option in the operation's
|
|
2712
|
+
`schemas/operations/*.yaml`); the transport bound is defence in
|
|
2713
|
+
depth, not the primary user-facing limit. See ADR-0009 §D5.
|
|
2714
|
+
items:
|
|
2715
|
+
$ref: '#/components/schemas/OperationResultOutputEntry'
|
|
2716
|
+
total_output_size_bytes:
|
|
2717
|
+
type: integer
|
|
2718
|
+
format: int64
|
|
2719
|
+
minimum: 0
|
|
2720
|
+
description: |
|
|
2721
|
+
Aggregate size of all `outputs[]` in bytes. Equals
|
|
2722
|
+
`sum(outputs[].output_size_bytes)`. Emitted only with multi-output
|
|
2723
|
+
completion. Used for billing and aggregate observability. Per
|
|
2724
|
+
ADR-0009 §D4, this is denormalised against the per-entry sum;
|
|
2725
|
+
consumers SHOULD trust the per-entry sum if the two disagree (and
|
|
2726
|
+
log a warning).
|
|
2727
|
+
example: 786432
|
|
2728
|
+
|
|
1769
2729
|
metrics:
|
|
1770
2730
|
$ref: '#/components/schemas/OperationMetrics'
|
|
1771
2731
|
|
|
@@ -1787,6 +2747,156 @@ components:
|
|
|
1787
2747
|
description: Progress percentage when the operation failed (failed only)
|
|
1788
2748
|
example: 10
|
|
1789
2749
|
|
|
2750
|
+
OperationResultOutputEntry:
|
|
2751
|
+
type: object
|
|
2752
|
+
description: |
|
|
2753
|
+
Single entry in the `OperationResult.outputs[]` array for multi-output
|
|
2754
|
+
operations. Per ADR-0009.
|
|
2755
|
+
|
|
2756
|
+
Each entry represents one output file produced by the operation, with
|
|
2757
|
+
its S3 key, size, and an indexing field (`page_index` for PDF-page
|
|
2758
|
+
outputs, `position` for generic ordinals). Per ADR-0009 §D2, an
|
|
2759
|
+
operation uses **one** indexing field consistently for all its
|
|
2760
|
+
outputs; the two are mutually exclusive within an entry.
|
|
2761
|
+
required:
|
|
2762
|
+
- output_key
|
|
2763
|
+
- output_size_bytes
|
|
2764
|
+
oneOf:
|
|
2765
|
+
- title: PageIndexed
|
|
2766
|
+
description: PDF-page output (convert PDF->image).
|
|
2767
|
+
required: [page_index]
|
|
2768
|
+
not: { required: [position] }
|
|
2769
|
+
- title: PositionIndexed
|
|
2770
|
+
description: Generic ordinal output (frame strip, chapter split).
|
|
2771
|
+
required: [position]
|
|
2772
|
+
not: { required: [page_index] }
|
|
2773
|
+
- title: Unindexed
|
|
2774
|
+
description: |
|
|
2775
|
+
Output without an explicit indexing field. Reserved for future
|
|
2776
|
+
operations that index by something other than page/position.
|
|
2777
|
+
Schema-valid but not currently emitted by any operation.
|
|
2778
|
+
not:
|
|
2779
|
+
anyOf:
|
|
2780
|
+
- required: [page_index]
|
|
2781
|
+
- required: [position]
|
|
2782
|
+
properties:
|
|
2783
|
+
output_key:
|
|
2784
|
+
type: string
|
|
2785
|
+
maxLength: 1024
|
|
2786
|
+
description: |
|
|
2787
|
+
S3 key of this individual output file. `maxLength: 1024` matches
|
|
2788
|
+
the S3 object key hard limit; keys longer than this are rejected
|
|
2789
|
+
by S3 itself, so this is a contract-level mirror of the upstream
|
|
2790
|
+
constraint.
|
|
2791
|
+
example: "jobs/018f9c42-5d6b/018f9c42-5d6b-e200/page-001.png"
|
|
2792
|
+
output_size_bytes:
|
|
2793
|
+
type: integer
|
|
2794
|
+
format: int64
|
|
2795
|
+
minimum: 0
|
|
2796
|
+
description: Size of this individual output file in bytes.
|
|
2797
|
+
example: 262144
|
|
2798
|
+
page_index:
|
|
2799
|
+
type: integer
|
|
2800
|
+
minimum: 1
|
|
2801
|
+
description: |
|
|
2802
|
+
1-based page number for PDF-page outputs. Gapless within an
|
|
2803
|
+
operation (an N-page conversion emits `page_index` 1..N). Mutually
|
|
2804
|
+
exclusive with `position`. Per ADR-0009 §D2.
|
|
2805
|
+
example: 1
|
|
2806
|
+
position:
|
|
2807
|
+
type: integer
|
|
2808
|
+
minimum: 0
|
|
2809
|
+
description: |
|
|
2810
|
+
0-based ordinal for non-PDF multi-output operations (e.g. frame
|
|
2811
|
+
strip, chapter split). Mutually exclusive with `page_index`.
|
|
2812
|
+
Per ADR-0009 §D2.
|
|
2813
|
+
example: 0
|
|
2814
|
+
|
|
2815
|
+
# ============================================
|
|
2816
|
+
# WORKFLOW STATE CHANGED (per ticket I24)
|
|
2817
|
+
# ============================================
|
|
2818
|
+
|
|
2819
|
+
WorkflowStateChanged:
|
|
2820
|
+
type: object
|
|
2821
|
+
description: |
|
|
2822
|
+
Workflow-level state-transition event published by the API
|
|
2823
|
+
when a workflow's `status` changes. Per ticket
|
|
2824
|
+
[I24 `e50uXLcl`](https://trello.com/c/e50uXLcl) + plan v5
|
|
2825
|
+
round 9.
|
|
2826
|
+
|
|
2827
|
+
Emitted on every transition (e.g. `pending → in_progress`,
|
|
2828
|
+
`in_progress → paused_insufficient_credits`,
|
|
2829
|
+
`paused_insufficient_credits → in_progress` after resume,
|
|
2830
|
+
`in_progress → cancelled`, `paused_insufficient_credits →
|
|
2831
|
+
expired`, the terminal `completed` / `failed` /
|
|
2832
|
+
`partially_failed`). The SSE stream's
|
|
2833
|
+
`workflow.completed` / `workflow.failed` /
|
|
2834
|
+
`workflow.partially_failed` events are the frontend-facing
|
|
2835
|
+
subset of these transitions; this event covers the full
|
|
2836
|
+
lifecycle for backend consumers (audit log, dashboards,
|
|
2837
|
+
webhook subscribers).
|
|
2838
|
+
|
|
2839
|
+
`reason` is a free-form string carrying advisory cause —
|
|
2840
|
+
same opacity precedent as `OperationMetrics.re_encode_reason`
|
|
2841
|
+
(per I16-CONS) and `SseWorkflowTerminalData.reason` (per
|
|
2842
|
+
I27). `billing_effect` is present only on transitions to
|
|
2843
|
+
`cancelled` or `expired` — both states release any unspent
|
|
2844
|
+
reservation portion (see `WorkflowCancelBillingEffect` in
|
|
2845
|
+
`openapi/api.yaml`).
|
|
2846
|
+
required:
|
|
2847
|
+
- workflow_id
|
|
2848
|
+
- previous_status
|
|
2849
|
+
- current_status
|
|
2850
|
+
- changed_at
|
|
2851
|
+
properties:
|
|
2852
|
+
workflow_id:
|
|
2853
|
+
type: string
|
|
2854
|
+
format: uuid
|
|
2855
|
+
description: UUID-v7 workflow identifier.
|
|
2856
|
+
previous_status:
|
|
2857
|
+
type: string
|
|
2858
|
+
enum:
|
|
2859
|
+
- pending
|
|
2860
|
+
- in_progress
|
|
2861
|
+
- completed
|
|
2862
|
+
- failed
|
|
2863
|
+
- partially_failed
|
|
2864
|
+
- paused_insufficient_credits
|
|
2865
|
+
- cancelled
|
|
2866
|
+
- expired
|
|
2867
|
+
current_status:
|
|
2868
|
+
type: string
|
|
2869
|
+
enum:
|
|
2870
|
+
- pending
|
|
2871
|
+
- in_progress
|
|
2872
|
+
- completed
|
|
2873
|
+
- failed
|
|
2874
|
+
- partially_failed
|
|
2875
|
+
- paused_insufficient_credits
|
|
2876
|
+
- cancelled
|
|
2877
|
+
- expired
|
|
2878
|
+
changed_at:
|
|
2879
|
+
type: string
|
|
2880
|
+
format: date-time
|
|
2881
|
+
reason:
|
|
2882
|
+
type: string
|
|
2883
|
+
description: |
|
|
2884
|
+
Optional advisory reason. Free-form string; not enumerated.
|
|
2885
|
+
Examples: `all jobs completed successfully`,
|
|
2886
|
+
`next reservation exceeded available_credits` (when
|
|
2887
|
+
transitioning to `paused_insufficient_credits`),
|
|
2888
|
+
`caller requested cancel`, `paused_insufficient_credits
|
|
2889
|
+
past expires_at`, `dispatch timeout`.
|
|
2890
|
+
billing_effect:
|
|
2891
|
+
type: string
|
|
2892
|
+
enum:
|
|
2893
|
+
- unspent_reservation_released
|
|
2894
|
+
- none
|
|
2895
|
+
description: |
|
|
2896
|
+
Present on transitions to `cancelled` or `expired`.
|
|
2897
|
+
Mirrors `WorkflowCancelBillingEffect` from
|
|
2898
|
+
`openapi/api.yaml`. Absent on other transitions.
|
|
2899
|
+
|
|
1790
2900
|
# ============================================
|
|
1791
2901
|
# METRICS
|
|
1792
2902
|
# ============================================
|
|
@@ -1801,7 +2911,7 @@ components:
|
|
|
1801
2911
|
original_size_bytes:
|
|
1802
2912
|
type: integer
|
|
1803
2913
|
format: int64
|
|
1804
|
-
description: Original file size in bytes (compress, convert, thumbnail,
|
|
2914
|
+
description: Original file size in bytes (compress, convert, thumbnail, image_watermark, text_watermark)
|
|
1805
2915
|
example: 5242880
|
|
1806
2916
|
output_size_bytes:
|
|
1807
2917
|
type: integer
|
|
@@ -1835,6 +2945,381 @@ components:
|
|
|
1835
2945
|
format: int64
|
|
1836
2946
|
description: Sum of all input file sizes (merge, archive)
|
|
1837
2947
|
example: 52428800
|
|
2948
|
+
re_encode_decision:
|
|
2949
|
+
# Named schema lifted from inline per ticket QokFw8VR.
|
|
2950
|
+
$ref: '#/components/schemas/ReEncodeDecision'
|
|
2951
|
+
re_encode_reason:
|
|
2952
|
+
type: string
|
|
2953
|
+
description: |
|
|
2954
|
+
Advisory explanation for `re_encode_decision` (e.g.
|
|
2955
|
+
`all_inputs_compatible`, `explicit_always_mode`,
|
|
2956
|
+
`input_codec_mismatch`, `input_framerate_mismatch`).
|
|
2957
|
+
Free-form string — not an enum — so the Lambda can emit
|
|
2958
|
+
human-readable diagnostics that evolve without contract
|
|
2959
|
+
churn (compatibility-probe algorithm stays opaque per
|
|
2960
|
+
plan v5 §F8.2). Per ticket I16-CONS.
|
|
2961
|
+
example: input_codec_mismatch
|
|
2962
|
+
|
|
2963
|
+
# ============================================
|
|
2964
|
+
# UPLOAD PROBE PAYLOADS (per ticket vBlEurU7)
|
|
2965
|
+
# ============================================
|
|
2966
|
+
|
|
2967
|
+
UploadProbeRequest:
|
|
2968
|
+
type: object
|
|
2969
|
+
description: |
|
|
2970
|
+
Request payload for the upload-probe Lambda. Shared between
|
|
2971
|
+
the synchronous Lambda RequestResponse path (backing
|
|
2972
|
+
`POST /api/uploads/{id}/probe`) and the asynchronous
|
|
2973
|
+
SNS->SQS->Lambda path (eager `rich_metadata` enrichment on
|
|
2974
|
+
upload finalize). Per ticket
|
|
2975
|
+
[vBlEurU7](https://trello.com/c/vBlEurU7) +
|
|
2976
|
+
[rdBHmTfa](https://trello.com/c/rdBHmTfa).
|
|
2977
|
+
|
|
2978
|
+
The Lambda detects which path it is on from the AWS event
|
|
2979
|
+
source structure — there is no flag in the payload that
|
|
2980
|
+
distinguishes sync vs async. The shape is intentionally
|
|
2981
|
+
small so SDK generators emit a single typed binding the API
|
|
2982
|
+
layer can construct from either invocation path.
|
|
2983
|
+
required:
|
|
2984
|
+
- file_id
|
|
2985
|
+
- source_bucket
|
|
2986
|
+
- source_key
|
|
2987
|
+
- file_type
|
|
2988
|
+
- idempotency_key
|
|
2989
|
+
properties:
|
|
2990
|
+
file_id:
|
|
2991
|
+
type: string
|
|
2992
|
+
format: uuid
|
|
2993
|
+
description: |
|
|
2994
|
+
Upload file identifier (UUID v7). Mirrors the path
|
|
2995
|
+
parameter on `POST /api/uploads/{id}/probe` for the sync
|
|
2996
|
+
path and the upload row's primary key for the async path.
|
|
2997
|
+
example: "019539ab-1111-7000-8000-000000000010"
|
|
2998
|
+
source_bucket:
|
|
2999
|
+
type: string
|
|
3000
|
+
description: |
|
|
3001
|
+
S3 bucket containing the uploaded file. Always the
|
|
3002
|
+
tenant-scoped input bucket
|
|
3003
|
+
(`gisl-{env}-{region}-input`).
|
|
3004
|
+
example: "gisl-stg-euw1-input"
|
|
3005
|
+
source_key:
|
|
3006
|
+
type: string
|
|
3007
|
+
description: |
|
|
3008
|
+
S3 key of the uploaded file under `source_bucket`.
|
|
3009
|
+
example: "uploads/019539ab-1111-7000-8000-000000000010/clip.mp4"
|
|
3010
|
+
file_type:
|
|
3011
|
+
type: string
|
|
3012
|
+
description: |
|
|
3013
|
+
MIME type of the uploaded file (e.g. `video/mp4`,
|
|
3014
|
+
`audio/mpeg`, `application/pdf`) as recorded on the
|
|
3015
|
+
upload row at finalize time. Field name follows the
|
|
3016
|
+
AsyncAPI events.yaml convention (`OperationRequest.file_type`
|
|
3017
|
+
and the rest of the message-payload schemas in this spec
|
|
3018
|
+
consistently use `file_type` for MIME, even though
|
|
3019
|
+
`openapi/api.yaml` uses `mime_type` for the same concept
|
|
3020
|
+
on the REST surface). The probe uses this as a hint for
|
|
3021
|
+
which extractor pipeline to run; mismatches against the
|
|
3022
|
+
actual container surface as `format_mismatch` in the
|
|
3023
|
+
completion's `error_code`.
|
|
3024
|
+
example: "video/mp4"
|
|
3025
|
+
idempotency_key:
|
|
3026
|
+
type: string
|
|
3027
|
+
minLength: 1
|
|
3028
|
+
maxLength: 200
|
|
3029
|
+
description: |
|
|
3030
|
+
Caller-supplied idempotency token. Echoed back on the
|
|
3031
|
+
`UploadProbeCompletion` (async branch) so the API
|
|
3032
|
+
consumer can deduplicate against the upload row.
|
|
3033
|
+
|
|
3034
|
+
Conventions:
|
|
3035
|
+
- Sync path: typically the `file_id` itself, since the
|
|
3036
|
+
probe is cached server-side per upload (see
|
|
3037
|
+
`UploadProbeMediaMetadata.probed_at` description in
|
|
3038
|
+
`openapi/api.yaml`).
|
|
3039
|
+
- Async path: the upload finalize event identifier
|
|
3040
|
+
(e.g. `upload-finalize:{file_id}`) so retries of the
|
|
3041
|
+
same finalize event collapse to a single completion.
|
|
3042
|
+
example: "upload-finalize:019539ab-1111-7000-8000-000000000010"
|
|
3043
|
+
requested_at:
|
|
3044
|
+
type: string
|
|
3045
|
+
format: date-time
|
|
3046
|
+
description: |
|
|
3047
|
+
ISO-8601 timestamp at which the probe request was issued.
|
|
3048
|
+
Optional; populated when the API publisher records it
|
|
3049
|
+
for log correlation. Not used by the Lambda for any
|
|
3050
|
+
decision.
|
|
3051
|
+
example: "2026-05-06T13:50:00Z"
|
|
3052
|
+
|
|
3053
|
+
UploadProbeCompletion:
|
|
3054
|
+
type: object
|
|
3055
|
+
description: |
|
|
3056
|
+
Completion payload published by the upload-probe Lambda to
|
|
3057
|
+
the `upload-probe-completions` SQS queue on the async
|
|
3058
|
+
branch. Mirrors `UploadProbeResponse` (`openapi/api.yaml`)
|
|
3059
|
+
for the success case and additionally carries failure
|
|
3060
|
+
fields (`error_code`, `error_message`) so the API consumer
|
|
3061
|
+
can persist Lambda-side failures (S3 download failed,
|
|
3062
|
+
decoder crashed, etc.) on the upload row alongside
|
|
3063
|
+
successful probes.
|
|
3064
|
+
|
|
3065
|
+
**Conditional schema (mirrors `OperationResult`):**
|
|
3066
|
+
- When `error_code` is **absent**, the payload is treated as
|
|
3067
|
+
a successful probe and `probe_status`,
|
|
3068
|
+
`processing_class_pre_assignment`, and `media_metadata`
|
|
3069
|
+
are REQUIRED.
|
|
3070
|
+
- When `error_code` is **present**, the payload is treated as
|
|
3071
|
+
a Lambda-side failure and only `error_code` +
|
|
3072
|
+
`error_message` are REQUIRED on top of the always-required
|
|
3073
|
+
identification + provenance fields. `probe_status` and
|
|
3074
|
+
peers MAY be absent in this case.
|
|
3075
|
+
|
|
3076
|
+
Note that `probe_status: corrupt` / `unsupported_codec` /
|
|
3077
|
+
`missing_metadata` are **successful** probes that report an
|
|
3078
|
+
unhealthy file — they do NOT populate `error_code`. Reserve
|
|
3079
|
+
`error_code` for "the probe pipeline itself failed".
|
|
3080
|
+
|
|
3081
|
+
Sync invocations do not produce this shape — they return
|
|
3082
|
+
`UploadProbeResponse` directly.
|
|
3083
|
+
required:
|
|
3084
|
+
- file_id
|
|
3085
|
+
- idempotency_key
|
|
3086
|
+
- probed_at
|
|
3087
|
+
- probe_version
|
|
3088
|
+
if:
|
|
3089
|
+
not:
|
|
3090
|
+
required:
|
|
3091
|
+
- error_code
|
|
3092
|
+
then:
|
|
3093
|
+
required:
|
|
3094
|
+
- probe_status
|
|
3095
|
+
- processing_class_pre_assignment
|
|
3096
|
+
- media_metadata
|
|
3097
|
+
else:
|
|
3098
|
+
required:
|
|
3099
|
+
- error_code
|
|
3100
|
+
- error_message
|
|
3101
|
+
properties:
|
|
3102
|
+
file_id:
|
|
3103
|
+
type: string
|
|
3104
|
+
format: uuid
|
|
3105
|
+
description: Upload file identifier (UUID v7) — correlation key.
|
|
3106
|
+
example: "019539ab-1111-7000-8000-000000000010"
|
|
3107
|
+
idempotency_key:
|
|
3108
|
+
type: string
|
|
3109
|
+
description: |
|
|
3110
|
+
Echoed from the originating `UploadProbeRequest` for
|
|
3111
|
+
deduplication on the API consumer side.
|
|
3112
|
+
example: "upload-finalize:019539ab-1111-7000-8000-000000000010"
|
|
3113
|
+
probe_status:
|
|
3114
|
+
$ref: '#/components/schemas/UploadProbeStatus'
|
|
3115
|
+
processing_class_pre_assignment:
|
|
3116
|
+
$ref: '#/components/schemas/UploadProbeProcessingClass'
|
|
3117
|
+
media_metadata:
|
|
3118
|
+
$ref: '#/components/schemas/UploadProbeMediaMetadata'
|
|
3119
|
+
error_code:
|
|
3120
|
+
type: string
|
|
3121
|
+
description: |
|
|
3122
|
+
Machine-readable error code when the probe pipeline
|
|
3123
|
+
itself failed. Reuses the same vocabulary as
|
|
3124
|
+
`OperationResult.error_code` where applicable
|
|
3125
|
+
(`s3_download_failed`, `s3_access_denied`, `timeout`,
|
|
3126
|
+
`out_of_memory`, `decode_failed`, `processing_failed`,
|
|
3127
|
+
`unknown`). Absent on successful probes — including
|
|
3128
|
+
probes that report `probe_status: corrupt /
|
|
3129
|
+
unsupported_codec / missing_metadata`, which are
|
|
3130
|
+
successful probes about an unhealthy file.
|
|
3131
|
+
example: "s3_download_failed"
|
|
3132
|
+
error_message:
|
|
3133
|
+
type: string
|
|
3134
|
+
description: |
|
|
3135
|
+
Human-readable error message paired with `error_code`.
|
|
3136
|
+
Absent on successful probes.
|
|
3137
|
+
example: "Failed to download source file from S3"
|
|
3138
|
+
probed_at:
|
|
3139
|
+
type: string
|
|
3140
|
+
format: date-time
|
|
3141
|
+
description: |
|
|
3142
|
+
ISO-8601 timestamp at which the probe ran (or attempted
|
|
3143
|
+
to run, for failure cases). Always present so the API
|
|
3144
|
+
consumer can timestamp the upload row regardless of
|
|
3145
|
+
outcome. For successful probes this matches
|
|
3146
|
+
`media_metadata.probed_at`; the duplicate top-level
|
|
3147
|
+
field exists so the failure case can still carry a
|
|
3148
|
+
timestamp even when `media_metadata` is omitted.
|
|
3149
|
+
example: "2026-05-06T13:50:01Z"
|
|
3150
|
+
probe_version:
|
|
3151
|
+
type: string
|
|
3152
|
+
description: |
|
|
3153
|
+
Semver of the upload-probe Lambda implementation that
|
|
3154
|
+
produced this completion. Useful for cache invalidation
|
|
3155
|
+
on the API side (re-probe when the prober ships a new
|
|
3156
|
+
extractor) and for log correlation.
|
|
3157
|
+
example: "1.0.0"
|
|
3158
|
+
|
|
3159
|
+
UploadProbeStatus:
|
|
3160
|
+
type: string
|
|
3161
|
+
description: |
|
|
3162
|
+
Outcome of a successful preflight probe. Mirrors
|
|
3163
|
+
`UploadProbeStatus` in `openapi/api.yaml` so SDK generators
|
|
3164
|
+
consuming both specs emit a single typed binding.
|
|
3165
|
+
|
|
3166
|
+
Cross-spec parity is verified by
|
|
3167
|
+
`tests/test_upload_probe_schemas.py` — the OpenAPI side is
|
|
3168
|
+
the source of truth for the value set.
|
|
3169
|
+
|
|
3170
|
+
Note: a `probe_status` value here means the probe pipeline
|
|
3171
|
+
succeeded. Lambda-side failures on the async branch are
|
|
3172
|
+
signalled via `UploadProbeCompletion.error_code` and do not
|
|
3173
|
+
require populating this field.
|
|
3174
|
+
enum:
|
|
3175
|
+
- ok
|
|
3176
|
+
- corrupt
|
|
3177
|
+
- unsupported_codec
|
|
3178
|
+
- missing_metadata
|
|
3179
|
+
|
|
3180
|
+
UploadProbeProcessingClass:
|
|
3181
|
+
type: string
|
|
3182
|
+
description: |
|
|
3183
|
+
Tier-aware pre-assignment. Mirrors
|
|
3184
|
+
`UploadProbeProcessingClass` in `openapi/api.yaml` so SDK
|
|
3185
|
+
generators consuming both specs emit a single typed binding.
|
|
3186
|
+
|
|
3187
|
+
Cross-spec parity is verified by
|
|
3188
|
+
`tests/test_upload_probe_schemas.py` — the OpenAPI side is
|
|
3189
|
+
the source of truth for the value set.
|
|
3190
|
+
enum:
|
|
3191
|
+
- short_form
|
|
3192
|
+
- long_form
|
|
3193
|
+
- blocked
|
|
3194
|
+
|
|
3195
|
+
UploadProbeMediaMetadata:
|
|
3196
|
+
type: object
|
|
3197
|
+
description: |
|
|
3198
|
+
Probe-extracted media metadata. Mirrors
|
|
3199
|
+
`UploadProbeMediaMetadata` in `openapi/api.yaml` so SDK
|
|
3200
|
+
generators consuming both specs emit a single typed binding
|
|
3201
|
+
instead of two `AnonymousSchema_N` placeholders.
|
|
3202
|
+
|
|
3203
|
+
AsyncAPI 3.0 cannot `$ref` across files into the OpenAPI
|
|
3204
|
+
spec, so the shape is duplicated here verbatim. Cross-spec
|
|
3205
|
+
parity is verified by
|
|
3206
|
+
`tests/test_upload_probe_schemas.py` — the OpenAPI side is
|
|
3207
|
+
the source of truth.
|
|
3208
|
+
|
|
3209
|
+
Schema covers the **union** of fields needed by the API's
|
|
3210
|
+
`MetadataResponse` projection across video / audio /
|
|
3211
|
+
document inputs (per the M2 Epic re-scope —
|
|
3212
|
+
[`SrHwuvIl`](https://trello.com/c/SrHwuvIl) — which makes
|
|
3213
|
+
this probe Lambda the universal non-image metadata source
|
|
3214
|
+
feeding `rich_metadata`). The Lambda extractor only
|
|
3215
|
+
populates fields it can derive from the actual container;
|
|
3216
|
+
unrelated fields are simply omitted (absent fields are NOT
|
|
3217
|
+
errors — they reflect "this metadata is not applicable /
|
|
3218
|
+
not extractable" rather than "this metadata failed
|
|
3219
|
+
validation"). `probed_at` is always present.
|
|
3220
|
+
required:
|
|
3221
|
+
- probed_at
|
|
3222
|
+
properties:
|
|
3223
|
+
duration_seconds:
|
|
3224
|
+
type: integer
|
|
3225
|
+
minimum: 0
|
|
3226
|
+
description: Container-reported duration (audio + video).
|
|
3227
|
+
width:
|
|
3228
|
+
type: integer
|
|
3229
|
+
minimum: 1
|
|
3230
|
+
description: Pixel width (image + video; best-effort document).
|
|
3231
|
+
height:
|
|
3232
|
+
type: integer
|
|
3233
|
+
minimum: 1
|
|
3234
|
+
description: Pixel height (image + video; best-effort document).
|
|
3235
|
+
codec:
|
|
3236
|
+
type: string
|
|
3237
|
+
description: |
|
|
3238
|
+
Primary codec identifier as reported by the prober. For
|
|
3239
|
+
video inputs this is the **video** codec; for audio-only
|
|
3240
|
+
inputs this is the audio codec. For video files with
|
|
3241
|
+
audio tracks, the audio codec is reported separately as
|
|
3242
|
+
`audio_codec`. Examples: `h264`, `h265`, `vp9`, `av1`,
|
|
3243
|
+
`aac`, `opus`, `mp3`. Not constrained to an enum — codec
|
|
3244
|
+
strings evolve with FFmpeg releases (per ADR-0007 FFmpeg
|
|
3245
|
+
pin) and SDKs should string-match.
|
|
3246
|
+
audio_codec:
|
|
3247
|
+
type: string
|
|
3248
|
+
description: |
|
|
3249
|
+
Audio codec for video files that carry an audio track.
|
|
3250
|
+
Distinct from `codec` (which is the video codec for
|
|
3251
|
+
video inputs). Absent for video-only / silent video
|
|
3252
|
+
inputs and for audio-only inputs (audio-only inputs put
|
|
3253
|
+
their codec under `codec`).
|
|
3254
|
+
container:
|
|
3255
|
+
type: string
|
|
3256
|
+
description: |
|
|
3257
|
+
Container format. Examples: `mp4`, `webm`, `mov`,
|
|
3258
|
+
`mkv`, `mp3`, `wav`, `flac`. Not constrained to an
|
|
3259
|
+
enum.
|
|
3260
|
+
fps:
|
|
3261
|
+
type: number
|
|
3262
|
+
minimum: 0
|
|
3263
|
+
description: |
|
|
3264
|
+
Container-reported frame rate (video only). Number, not
|
|
3265
|
+
integer — frame rates are commonly fractional (e.g.
|
|
3266
|
+
`29.97`, `23.976`).
|
|
3267
|
+
bitrate_bps:
|
|
3268
|
+
type: integer
|
|
3269
|
+
minimum: 0
|
|
3270
|
+
description: |
|
|
3271
|
+
Overall stream bitrate, **bits per second**. Units in
|
|
3272
|
+
the field name, mirroring `duration_seconds`, so SDKs
|
|
3273
|
+
avoid the kbps-vs-bps guessing trap. Container-reported
|
|
3274
|
+
for video + audio.
|
|
3275
|
+
audio_layout:
|
|
3276
|
+
type: string
|
|
3277
|
+
description: |
|
|
3278
|
+
Channel layout, human-display form. Examples: `mono`,
|
|
3279
|
+
`stereo`, `5.1`, `7.1`. Not constrained. Pairs with the
|
|
3280
|
+
numeric `channels` field (which is what API consumers
|
|
3281
|
+
project into `rich_metadata`); `audio_layout` is
|
|
3282
|
+
preserved on the probe row for UI display ("5.1
|
|
3283
|
+
surround") without forcing the UI to derive a label
|
|
3284
|
+
from the integer.
|
|
3285
|
+
channels:
|
|
3286
|
+
type: integer
|
|
3287
|
+
minimum: 1
|
|
3288
|
+
description: |
|
|
3289
|
+
Numeric audio channel count derived by the Lambda from
|
|
3290
|
+
ffprobe output. Examples: `1` (mono), `2` (stereo), `6`
|
|
3291
|
+
(5.1), `8` (7.1). Pairs with `audio_layout`. Audio +
|
|
3292
|
+
video.
|
|
3293
|
+
sample_rate_hz:
|
|
3294
|
+
type: integer
|
|
3295
|
+
minimum: 1
|
|
3296
|
+
description: |
|
|
3297
|
+
Audio sample rate, **Hertz**. Units in the field name,
|
|
3298
|
+
mirroring `duration_seconds` / `bitrate_bps`. Examples:
|
|
3299
|
+
`44100`, `48000`. Audio + video-with-audio.
|
|
3300
|
+
page_count:
|
|
3301
|
+
type: integer
|
|
3302
|
+
minimum: 0
|
|
3303
|
+
description: |
|
|
3304
|
+
Document page count (PDF / EPUB / DOCX / XLSX / PPTX /
|
|
3305
|
+
ODT / ODS / ODP). `0` for a document the prober opened
|
|
3306
|
+
but found empty.
|
|
3307
|
+
dpi:
|
|
3308
|
+
type: integer
|
|
3309
|
+
minimum: 1
|
|
3310
|
+
description: |
|
|
3311
|
+
Document resolution, single-axis (dots per inch).
|
|
3312
|
+
Single-axis matches the existing `MetadataResponse`
|
|
3313
|
+
contract on the OpenAPI side; the prober reports the
|
|
3314
|
+
page-1 horizontal DPI when the document declares it,
|
|
3315
|
+
otherwise omits the field.
|
|
3316
|
+
probed_at:
|
|
3317
|
+
type: string
|
|
3318
|
+
format: date-time
|
|
3319
|
+
description: |
|
|
3320
|
+
ISO-8601 timestamp at which the probe ran. Idempotent
|
|
3321
|
+
for the same `file_id` — subsequent probe calls return
|
|
3322
|
+
the cached `probed_at`.
|
|
1838
3323
|
|
|
1839
3324
|
# ============================================
|
|
1840
3325
|
# ENUMS
|
|
@@ -1843,52 +3328,102 @@ components:
|
|
|
1843
3328
|
OperationType:
|
|
1844
3329
|
type: string
|
|
1845
3330
|
description: |
|
|
1846
|
-
Operation type
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
`
|
|
3331
|
+
Operation type as carried inside the message **payload** body. This
|
|
3332
|
+
enum is deliberately narrower than the SNS `operation_type`
|
|
3333
|
+
MessageAttribute: the attribute enum permits per-media thumbnail
|
|
3334
|
+
sub-types (`thumbnail_image`, `thumbnail_video`,
|
|
3335
|
+
`thumbnail_document`, `thumbnail_office`) for routing on the
|
|
3336
|
+
`operations` topic, but the payload body always carries the
|
|
3337
|
+
semantic base value (`thumbnail`). See
|
|
3338
|
+
`OperationRequestAttributes.operation_type` for the broader
|
|
3339
|
+
attribute enum and the routing contract. Note that the attribute
|
|
3340
|
+
values the publisher currently emits are governed by the
|
|
3341
|
+
thumbnail migration-window note (top-level `info.description`
|
|
3342
|
+
and `OperationRequestMessage.description`).
|
|
3343
|
+
|
|
3344
|
+
Compression operations are routed by `job_type` on the separate
|
|
3345
|
+
`job-requests` topic — see `JobRequestAttributes` and the top-level
|
|
3346
|
+
`info.description`.
|
|
1851
3347
|
|
|
1852
3348
|
- `compress`: Reduce file size (image, video, audio, document).
|
|
1853
3349
|
Routes via `job_type` on the `job-requests` topic.
|
|
1854
|
-
- `thumbnail`:
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
3350
|
+
- `thumbnail`: Thumbnail generation. The payload always carries
|
|
3351
|
+
the base value; the SNS `operation_type` attribute enum
|
|
3352
|
+
additionally permits one of the four sub-type values
|
|
3353
|
+
(`thumbnail_image`, `thumbnail_video`, `thumbnail_document`,
|
|
3354
|
+
`thumbnail_office`) for routing the request to the matching
|
|
3355
|
+
per-media Lambda. During the migration window, the legacy
|
|
3356
|
+
`operation_type=thumbnail` attribute value also remains a
|
|
3357
|
+
valid routing target (to `ops-thumbnail`). See the
|
|
3358
|
+
migration-window note for which values the publisher currently
|
|
3359
|
+
emits.
|
|
3360
|
+
- `image_watermark`: Apply image overlay (file or external_source)
|
|
3361
|
+
onto a base media asset (Path B multi-input with role
|
|
3362
|
+
base+overlay per JobInputV2.role). Stable for static-image bases
|
|
3363
|
+
(image/jpeg, image/png, image/webp); animated GIF and video
|
|
3364
|
+
bases are advertised in `image_watermark.yaml` as `planned` via
|
|
3365
|
+
parallel mime_groups (`image_gif`, `video`) — dispatch returns
|
|
3366
|
+
`feature_not_available` (422) until Lambda support ships.
|
|
3367
|
+
Routes via `operation_type=image_watermark` to
|
|
3368
|
+
`ops-image-watermark`. Per ADR-0004 + I4-CONS + I5 (Trello
|
|
3369
|
+
AKZiOXnd).
|
|
3370
|
+
- `text_watermark`: Render a text overlay (Liberation Sans) onto
|
|
3371
|
+
an image. Single-input. Routes via
|
|
3372
|
+
`operation_type=text_watermark` to `ops-text-watermark`.
|
|
3373
|
+
Per ADR-0004 + I4-CONS.
|
|
1873
3374
|
- `convert`: Change file format (image, video, audio, document).
|
|
1874
3375
|
Routes via `operation_type=convert` to `ops-convert`.
|
|
1875
3376
|
- `merge`: Concatenate/combine multiple files (image, video,
|
|
1876
|
-
audio
|
|
1877
|
-
|
|
3377
|
+
audio). Image inputs merge into animated GIF or slideshow
|
|
3378
|
+
video; image collage/grid and PDF concatenation are not
|
|
3379
|
+
supported by the V1 Lambda. Routes via `operation_type=merge`
|
|
3380
|
+
to `ops-merge`. A single Lambda handles the supported merge
|
|
3381
|
+
output types.
|
|
1878
3382
|
- `archive`: Bundle files into ZIP/tar.gz (media-agnostic).
|
|
1879
3383
|
Routes via `operation_type=archive` to `ops-archive`. No
|
|
1880
3384
|
`media_group` attribute is set for archive.
|
|
3385
|
+
- `custom_luma`: Apply a caller-uploaded luma matte to a base
|
|
3386
|
+
video for a custom luma-matte transition effect. Multi-input
|
|
3387
|
+
(Path B with `role: base` + `role: transition_mask` per
|
|
3388
|
+
`JobInputV2.role`). `availability: planned` +
|
|
3389
|
+
`required_tier: pro` per the operation schema; the API
|
|
3390
|
+
rejects workflow-create with `feature_not_available` (422)
|
|
3391
|
+
until the Lambda ships, so traffic does not reach SNS today.
|
|
3392
|
+
When Lambda support lands, routes via
|
|
3393
|
+
`operation_type=custom_luma` to `ops-custom-luma`. Per ADR-
|
|
3394
|
+
0004 + I29 (Trello EPUE5Vs1).
|
|
3395
|
+
- `audio_overlay`: Mix a secondary audio asset over a primary
|
|
3396
|
+
audio or video base (DJ tags, podcast intros/outros, station
|
|
3397
|
+
IDs, jingles). Multi-input (Path B with `role: base` +
|
|
3398
|
+
`role: overlay` per `JobInputV2.role`). Both mime_groups
|
|
3399
|
+
(`audio`, `video`) are `availability: planned` per the
|
|
3400
|
+
operation schema; the API rejects workflow-create with
|
|
3401
|
+
`feature_not_available` (422) until the Lambda ships, so
|
|
3402
|
+
traffic does not reach SNS today. **NOT** the same as
|
|
3403
|
+
`audio_watermark` (steganographic, owned by I20). Per ADR-
|
|
3404
|
+
0004 + I19 (Trello Xr3Z4GBF).
|
|
3405
|
+
- `audio_watermark`: Embed a steganographic forensic watermark
|
|
3406
|
+
into an audio asset (or a video's audio track) — Cinavia /
|
|
3407
|
+
Resemble PerTh territory. Single-input. Both mime_groups
|
|
3408
|
+
(`audio`, `video` — embed in video's audio track) are
|
|
3409
|
+
`availability: planned` + `required_tier: enterprise` per
|
|
3410
|
+
the operation schema; the API rejects workflow-create with
|
|
3411
|
+
`feature_not_available` (422) + `feature_tier_restricted`
|
|
3412
|
+
(403) until the Lambda ships, so traffic does not reach SNS
|
|
3413
|
+
today. Pairs with `POST /api/audio-watermark/decode` for
|
|
3414
|
+
own-watermarks-only extraction. Per ADR-0004 + I20 (Trello
|
|
3415
|
+
omiCq7Vn).
|
|
1881
3416
|
enum:
|
|
1882
3417
|
- compress
|
|
1883
3418
|
- thumbnail
|
|
1884
|
-
-
|
|
1885
|
-
-
|
|
1886
|
-
- thumbnail_document
|
|
1887
|
-
- thumbnail_office
|
|
1888
|
-
- watermark
|
|
3419
|
+
- image_watermark
|
|
3420
|
+
- text_watermark
|
|
1889
3421
|
- convert
|
|
1890
3422
|
- merge
|
|
1891
3423
|
- archive
|
|
3424
|
+
- custom_luma
|
|
3425
|
+
- audio_overlay
|
|
3426
|
+
- audio_watermark
|
|
1892
3427
|
|
|
1893
3428
|
MediaGroup:
|
|
1894
3429
|
type: string
|
|
@@ -1909,10 +3444,9 @@ components:
|
|
|
1909
3444
|
ODS, ODP)
|
|
1910
3445
|
|
|
1911
3446
|
For merge, derived from `output_type`:
|
|
1912
|
-
- output_type=
|
|
3447
|
+
- output_type=gif -> image
|
|
1913
3448
|
- output_type=video -> video
|
|
1914
3449
|
- output_type=audio -> audio
|
|
1915
|
-
- output_type=document -> document
|
|
1916
3450
|
|
|
1917
3451
|
Omitted from the SNS attributes for archive (media-agnostic). The
|
|
1918
3452
|
four thumbnail sub-types map to media_group as follows:
|
|
@@ -1935,30 +3469,101 @@ components:
|
|
|
1935
3469
|
regardless of the `output_type` value — `output_type` is read by
|
|
1936
3470
|
the merge Lambda to decide the internal encoding path and output
|
|
1937
3471
|
format, not to influence SNS routing.
|
|
1938
|
-
- `image`: Collage/grid (ImageMagick montage inside the merge Lambda)
|
|
1939
3472
|
- `gif`: Animated GIF (ImageMagick convert inside the merge Lambda)
|
|
1940
3473
|
- `video`: Slideshow from images or video concatenation (FFmpeg inside the merge Lambda)
|
|
1941
3474
|
- `audio`: Audio concatenation (FFmpeg inside the merge Lambda)
|
|
1942
|
-
- `document`: PDF concatenation (qpdf inside the merge Lambda)
|
|
1943
3475
|
enum:
|
|
1944
|
-
- image
|
|
1945
3476
|
- gif
|
|
1946
3477
|
- video
|
|
1947
3478
|
- audio
|
|
1948
|
-
|
|
3479
|
+
|
|
3480
|
+
JobInputRole:
|
|
3481
|
+
type: string
|
|
3482
|
+
description: |
|
|
3483
|
+
Role for role-based multi-input operations. Mirrors
|
|
3484
|
+
`JobInputV2.role` in `openapi/api.yaml`:
|
|
3485
|
+
- `image_watermark`: REQUIRED on each entry — exactly
|
|
3486
|
+
one `base` + one `overlay` per job (per ticket I4-CONS).
|
|
3487
|
+
- `custom_luma`: REQUIRED — exactly one `base` + one
|
|
3488
|
+
`transition_mask` per job (per ticket I29).
|
|
3489
|
+
- `audio_overlay`: REQUIRED — exactly one `base` + one
|
|
3490
|
+
`overlay` per job (per ticket I19); reuses
|
|
3491
|
+
`image_watermark`'s role values.
|
|
3492
|
+
- `merge` / `archive`: omit (all inputs share the same
|
|
3493
|
+
role). Future operations may widen this enum.
|
|
3494
|
+
|
|
3495
|
+
Named-schema form lifted from inline at `SourceEntry.role`
|
|
3496
|
+
per ticket QokFw8VR. The OpenAPI side at `JobInputV2.role`
|
|
3497
|
+
remains an inline enum today — symmetric extraction tracked
|
|
3498
|
+
as a follow-up; value-set parity is verified by inspection
|
|
3499
|
+
(both lists must remain identical).
|
|
3500
|
+
enum:
|
|
3501
|
+
- base
|
|
3502
|
+
- overlay
|
|
3503
|
+
- transition_mask
|
|
3504
|
+
|
|
3505
|
+
ReEncodeDecision:
|
|
3506
|
+
type: string
|
|
3507
|
+
description: |
|
|
3508
|
+
Path chosen for `merge.video` when `re_encode_mode=auto`.
|
|
3509
|
+
Server reports the actual path so callers can see why
|
|
3510
|
+
`auto` took the slow path. Absent for non-`merge.video`
|
|
3511
|
+
operations and for `merge.video` when `re_encode_mode` is
|
|
3512
|
+
`always` or `never` (path was caller-fixed). Per ticket
|
|
3513
|
+
I16-CONS (Trello 7nCZXEru). Workflow-create-time surface
|
|
3514
|
+
on `processing_plan.jobs[]` lands with I15-CONS
|
|
3515
|
+
(Trello YZpBKzOM).
|
|
3516
|
+
|
|
3517
|
+
Named-schema form lifted from inline at
|
|
3518
|
+
`OperationMetrics.re_encode_decision` per ticket QokFw8VR.
|
|
3519
|
+
enum:
|
|
3520
|
+
- stream_copy
|
|
3521
|
+
- re_encode
|
|
1949
3522
|
|
|
1950
3523
|
ProgressStatus:
|
|
1951
3524
|
type: string
|
|
1952
3525
|
description: |
|
|
1953
|
-
Status values for progress updates (non-terminal)
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
3526
|
+
Status values for progress updates (non-terminal). Backwards-
|
|
3527
|
+
compatibly extended for long-form video operations per ticket
|
|
3528
|
+
[I27 `1R3K3bsG`](https://trello.com/c/1R3K3bsG) + plan v5
|
|
3529
|
+
§F8.3 round 10 — the `probing` / `decoding` / `encoding`
|
|
3530
|
+
statuses give callers visibility into long-form jobs that
|
|
3531
|
+
internally process inputs sequentially without forcing
|
|
3532
|
+
callers to decompose into multiple jobs.
|
|
3533
|
+
|
|
3534
|
+
Non-long-form operations continue to emit only `started` /
|
|
3535
|
+
`downloading` / `processing` / `uploading` (the V1 pattern);
|
|
3536
|
+
clients that don't need phase visibility can ignore the new
|
|
3537
|
+
statuses without behavioural change.
|
|
3538
|
+
|
|
3539
|
+
- `started`: Lambda picked up the operation.
|
|
3540
|
+
- `downloading`: Downloading source file(s) from S3.
|
|
3541
|
+
- `probing`: Long-form video — server-side metadata probe
|
|
3542
|
+
on inputs (codec / container / framerate / resolution
|
|
3543
|
+
/ pixel-format detection driving `re_encode_decision`).
|
|
3544
|
+
Pairs with `phase_input_index` / `phase_total_inputs` so
|
|
3545
|
+
the frontend can render "probing input 2/4". Per I15-CONS
|
|
3546
|
+
/ I16-CONS.
|
|
3547
|
+
- `decoding`: Long-form video — decoding inputs ahead of
|
|
3548
|
+
the encode pass. Pairs with `phase_*` fields.
|
|
3549
|
+
- `processing`: Actively processing (compressing, merging,
|
|
3550
|
+
watermarking, etc.). The catch-all phase used by
|
|
3551
|
+
short-form operations and short-form-equivalent stages of
|
|
3552
|
+
long-form operations. May pair with `phase_*` fields when
|
|
3553
|
+
the operation is long-form.
|
|
3554
|
+
- `encoding`: Long-form video — explicit encode-pass status
|
|
3555
|
+
(vs the umbrella `processing`). Surfaces "encoding output
|
|
3556
|
+
42%" when the encode pass is long enough to deserve
|
|
3557
|
+
dedicated visibility. May pair with `phase_*` fields for
|
|
3558
|
+
multi-output operations.
|
|
3559
|
+
- `uploading`: Uploading result to S3.
|
|
1958
3560
|
enum:
|
|
1959
3561
|
- started
|
|
1960
3562
|
- downloading
|
|
3563
|
+
- probing
|
|
3564
|
+
- decoding
|
|
1961
3565
|
- processing
|
|
3566
|
+
- encoding
|
|
1962
3567
|
- uploading
|
|
1963
3568
|
|
|
1964
3569
|
ResultStatus:
|