package api import "time" // Category is one entry of the fixed category lookup table. Its ID is what // clients send back in CompleteRequest.CategoryIDs. type Category struct { ID int16 `json:"id" example:"1"` Name string `json:"name" example:"documentary"` } // CategoriesResponse is the body of GET /api/categories. type CategoriesResponse struct { Categories []Category `json:"categories"` } // PresignRequest is the body of POST /api/videos/presign. type PresignRequest struct { FileName string `json:"fileName" example:"interview-cut.mov"` ContentType string `json:"contentType" enums:"video/mp4,video/quicktime" example:"video/quicktime"` } // PresignResponse is the body returned by POST /api/videos/presign. type PresignResponse struct { UploadURL string `json:"uploadUrl" example:"https://raw-uploads-bucket.s3.amazonaws.com/videos/a1b2....mov?X-Amz-Signature=..."` Key string `json:"key" example:"videos/a1b2c3d4e5f6.mov"` } // CompleteRequest is the body of POST /api/videos. CategoryIDs holds ids from // GET /api/categories, not category names, and must carry at least one — a // video with no category is rejected. type CompleteRequest struct { Title string `json:"title" example:"Inside the Newsroom"` Description string `json:"description" example:"A behind-the-scenes look at the evening bulletin."` CategoryIDs []int16 `json:"categoryIds" example:"1,2"` Tags string `json:"tags" example:"media, press, riyadh"` FileName string `json:"fileName" example:"interview-cut.mov"` Key string `json:"key" example:"videos/a1b2c3d4e5f6.mov"` } // CompleteResponse is a persisted video record as returned by POST /api/videos. // Status carries the values of services.VideoStatus; the enums tag has to be // widened by hand whenever that type gains a state. type CompleteResponse struct { ID string `json:"id" example:"0199f3a1-7c2e-7b21-9f0d-1a2b3c4d5e6f"` Title string `json:"title" example:"Inside the Newsroom"` Description string `json:"description" example:"A behind-the-scenes look at the evening bulletin."` CategoryIDs []int16 `json:"categoryIds" example:"1,2"` Tags string `json:"tags" example:"media, press, riyadh"` FileName string `json:"fileName" example:"interview-cut.mov"` StorageKey string `json:"storageKey" example:"videos/a1b2c3d4e5f6.mov"` MediaConvertJobID string `json:"mediaConvertJobId" example:"1755300000000-abcdef"` Status string `json:"status" enums:"processing,ready,failed" example:"processing"` SizeBytes int64 `json:"sizeBytes" example:"60"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } // VideoResponse is a persisted video record as returned by // GET /api/videos/{id}. It carries the same members as CompleteResponse — // deliberately a separate type, so the shape POST publishes and the shape GET // publishes can diverge without one silently dragging the other with it. type VideoResponse struct { ID string `json:"id" example:"0199f3a1-7c2e-7b21-9f0d-1a2b3c4d5e6f"` Title string `json:"title" example:"Inside the Newsroom"` Description string `json:"description" example:"A behind-the-scenes look at the evening bulletin."` CategoryIDs []int16 `json:"categoryIds" example:"1,2"` Tags string `json:"tags" example:"media, press, riyadh"` FileName string `json:"fileName" example:"interview-cut.mov"` StorageKey string `json:"storageKey" example:"videos/a1b2c3d4e5f6.mov"` MediaConvertJobID string `json:"mediaConvertJobId" example:"1755300000000-abcdef"` Status string `json:"status" enums:"processing,ready,failed" example:"processing"` SizeBytes int64 `json:"sizeBytes" example:"60"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` }