377 lines
14 KiB
Go
377 lines
14 KiB
Go
// Package docs Code generated by swaggo/swag. DO NOT EDIT
|
|
package docs
|
|
|
|
import "github.com/swaggo/swag"
|
|
|
|
const docTemplate = `{
|
|
"schemes": {{ marshal .Schemes }},
|
|
"swagger": "2.0",
|
|
"info": {
|
|
"description": "{{escape .Description}}",
|
|
"title": "{{.Title}}",
|
|
"contact": {},
|
|
"version": "{{.Version}}"
|
|
},
|
|
"host": "{{.Host}}",
|
|
"basePath": "{{.BasePath}}",
|
|
"paths": {
|
|
"/api/categories": {
|
|
"get": {
|
|
"description": "Returns the fixed lookup set of categories a video can belong to, each with the id used to reference it. The ` + "`" + `id` + "`" + ` values from this list are the only ones accepted in the ` + "`" + `categoryIds` + "`" + ` field of POST /api/videos.",
|
|
"produces": [
|
|
"application/json"
|
|
],
|
|
"tags": [
|
|
"categories"
|
|
],
|
|
"summary": "List video categories",
|
|
"responses": {
|
|
"200": {
|
|
"description": "OK",
|
|
"schema": {
|
|
"$ref": "#/definitions/api.CategoriesResponse"
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Categories could not be read from the database",
|
|
"schema": {
|
|
"$ref": "#/definitions/api.ProblemDetails"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/videos": {
|
|
"post": {
|
|
"description": "Step 2 of the upload flow. Takes the storage key returned by POST /api/videos/presign — after the file has been PUT to the presigned URL — submits a MediaConvert transcoding job, and persists the video with its category links. The returned record has status \"processing\" — one of the states \"processing\", \"ready\" or \"failed\" — though nothing currently moves it on once transcoding finishes.",
|
|
"consumes": [
|
|
"application/json"
|
|
],
|
|
"produces": [
|
|
"application/json"
|
|
],
|
|
"tags": [
|
|
"videos"
|
|
],
|
|
"summary": "Register an uploaded video",
|
|
"parameters": [
|
|
{
|
|
"description": "Video metadata plus the storage key from the presign step. title, key and categoryIds are required; categoryIds must hold at least one id from GET /api/categories.",
|
|
"name": "request",
|
|
"in": "body",
|
|
"required": true,
|
|
"schema": {
|
|
"$ref": "#/definitions/api.CompleteRequest"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"201": {
|
|
"description": "Created",
|
|
"schema": {
|
|
"$ref": "#/definitions/api.CompleteResponse"
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Request body was not valid JSON",
|
|
"schema": {
|
|
"$ref": "#/definitions/api.ProblemDetails"
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "categoryIds referenced a category that does not exist",
|
|
"schema": {
|
|
"$ref": "#/definitions/api.ProblemDetails"
|
|
}
|
|
},
|
|
"422": {
|
|
"description": "title was empty, key was missing or not a key issued by this API, or categoryIds was empty",
|
|
"schema": {
|
|
"$ref": "#/definitions/api.ProblemDetails"
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Categories could not be read, the transcoding job could not be queued, or the video record could not be saved",
|
|
"schema": {
|
|
"$ref": "#/definitions/api.ProblemDetails"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/api/videos/presign": {
|
|
"post": {
|
|
"description": "Step 1 of the upload flow. Returns a short-lived presigned S3 URL that the client PUTs the video file to directly, plus the storage key identifying it. The submitted contentType is signed into that URL, so the PUT must carry an identical Content-Type header or S3 rejects it as a signature mismatch. Once the PUT succeeds, pass the key to POST /api/videos to register the video and start transcoding. The file itself never passes through this API.",
|
|
"consumes": [
|
|
"application/json"
|
|
],
|
|
"produces": [
|
|
"application/json"
|
|
],
|
|
"tags": [
|
|
"videos"
|
|
],
|
|
"summary": "Create a presigned upload URL",
|
|
"parameters": [
|
|
{
|
|
"description": "Name and media type of the file to be uploaded. contentType must be exactly 'video/mp4' or 'video/quicktime'.",
|
|
"name": "request",
|
|
"in": "body",
|
|
"required": true,
|
|
"schema": {
|
|
"$ref": "#/definitions/api.PresignRequest"
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "OK",
|
|
"schema": {
|
|
"$ref": "#/definitions/api.PresignResponse"
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Request body was not valid JSON",
|
|
"schema": {
|
|
"$ref": "#/definitions/api.ProblemDetails"
|
|
}
|
|
},
|
|
"422": {
|
|
"description": "contentType was not 'video/mp4' or 'video/quicktime'",
|
|
"schema": {
|
|
"$ref": "#/definitions/api.ProblemDetails"
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Upload URL could not be issued",
|
|
"schema": {
|
|
"$ref": "#/definitions/api.ProblemDetails"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/health": {
|
|
"get": {
|
|
"description": "Reports that the service is up and serving. Used as the ALB target group health check; it does not verify the database or S3 connections.",
|
|
"produces": [
|
|
"application/json"
|
|
],
|
|
"tags": [
|
|
"system"
|
|
],
|
|
"summary": "Health check",
|
|
"responses": {
|
|
"200": {
|
|
"description": "OK",
|
|
"schema": {
|
|
"$ref": "#/definitions/api.HealthResponse"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"definitions": {
|
|
"api.CategoriesResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"categories": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/api.Category"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"api.Category": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "integer",
|
|
"example": 1
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"example": "documentary"
|
|
}
|
|
}
|
|
},
|
|
"api.CompleteRequest": {
|
|
"type": "object",
|
|
"properties": {
|
|
"categoryIds": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "integer"
|
|
},
|
|
"example": [
|
|
1,
|
|
2
|
|
]
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"example": "A behind-the-scenes look at the evening bulletin."
|
|
},
|
|
"fileName": {
|
|
"type": "string",
|
|
"example": "interview-cut.mov"
|
|
},
|
|
"key": {
|
|
"type": "string",
|
|
"example": "videos/a1b2c3d4e5f6.mov"
|
|
},
|
|
"tags": {
|
|
"type": "string",
|
|
"example": "media, press, riyadh"
|
|
},
|
|
"title": {
|
|
"type": "string",
|
|
"example": "Inside the Newsroom"
|
|
}
|
|
}
|
|
},
|
|
"api.CompleteResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"categoryIds": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "integer"
|
|
},
|
|
"example": [
|
|
1,
|
|
2
|
|
]
|
|
},
|
|
"createdAt": {
|
|
"type": "string"
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"example": "A behind-the-scenes look at the evening bulletin."
|
|
},
|
|
"fileName": {
|
|
"type": "string",
|
|
"example": "interview-cut.mov"
|
|
},
|
|
"id": {
|
|
"type": "string",
|
|
"example": "0199f3a1-7c2e-7b21-9f0d-1a2b3c4d5e6f"
|
|
},
|
|
"mediaConvertJobId": {
|
|
"type": "string",
|
|
"example": "1755300000000-abcdef"
|
|
},
|
|
"sizeBytes": {
|
|
"type": "integer",
|
|
"example": 60
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"enum": [
|
|
"processing",
|
|
"ready",
|
|
"failed"
|
|
],
|
|
"example": "processing"
|
|
},
|
|
"storageKey": {
|
|
"type": "string",
|
|
"example": "videos/a1b2c3d4e5f6.mov"
|
|
},
|
|
"tags": {
|
|
"type": "string",
|
|
"example": "media, press, riyadh"
|
|
},
|
|
"title": {
|
|
"type": "string",
|
|
"example": "Inside the Newsroom"
|
|
},
|
|
"updatedAt": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"api.HealthResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"status": {
|
|
"type": "string",
|
|
"example": "ok"
|
|
}
|
|
}
|
|
},
|
|
"api.PresignRequest": {
|
|
"type": "object",
|
|
"properties": {
|
|
"contentType": {
|
|
"type": "string",
|
|
"enum": [
|
|
"video/mp4",
|
|
"video/quicktime"
|
|
],
|
|
"example": "video/quicktime"
|
|
},
|
|
"fileName": {
|
|
"type": "string",
|
|
"example": "interview-cut.mov"
|
|
}
|
|
}
|
|
},
|
|
"api.PresignResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"key": {
|
|
"type": "string",
|
|
"example": "videos/a1b2c3d4e5f6.mov"
|
|
},
|
|
"uploadUrl": {
|
|
"type": "string",
|
|
"example": "https://raw-uploads-bucket.s3.amazonaws.com/videos/a1b2....mov?X-Amz-Signature=..."
|
|
}
|
|
}
|
|
},
|
|
"api.ProblemDetails": {
|
|
"type": "object",
|
|
"properties": {
|
|
"detail": {
|
|
"type": "string",
|
|
"example": "The 'title' field was absent or contained only whitespace. Every video needs a non-empty title."
|
|
},
|
|
"status": {
|
|
"type": "integer",
|
|
"example": 422
|
|
},
|
|
"title": {
|
|
"type": "string",
|
|
"example": "Title is required."
|
|
},
|
|
"type": {
|
|
"type": "string",
|
|
"example": "about:blank"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}`
|
|
|
|
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
|
var SwaggerInfo = &swag.Spec{
|
|
Version: "1.0",
|
|
Host: "",
|
|
BasePath: "/",
|
|
Schemes: []string{},
|
|
Title: "Thamanyah CMS API",
|
|
Description: "JSON API for ingesting videos into the Thamanyah catalogue. Uploads are two-step: presign, PUT the file straight to S3, then register the video to queue transcoding.",
|
|
InfoInstanceName: "swagger",
|
|
SwaggerTemplate: docTemplate,
|
|
LeftDelim: "{{",
|
|
RightDelim: "}}",
|
|
}
|
|
|
|
func init() {
|
|
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
|
|
}
|