# JSON Media Integration Guide (Admin Panel) This guide documents the new media integration pattern introduced in the backend: - Upload binary file once through `POST /api/v1/files/upload` - Use the returned URL/key in JSON request bodies for business endpoints This replaces direct form-data usage in common admin flows (while legacy multipart compatibility still exists). --- ## 1) New General Media Upload Endpoint ### `POST /api/v1/files/upload` **Auth:** Bearer token required **Content-Type:** `multipart/form-data` **Purpose:** Upload media and return reference data for subsequent JSON requests. ### Request fields - `media_type` (required): `image` | `audio` | `video` - `file` (required): binary file - `title` (optional, video only): Vimeo video title - `description` (optional, video only): Vimeo video description ### Storage behavior - `media_type=image` -> MinIO - `media_type=audio` -> MinIO - `media_type=video` -> Vimeo ### Success response shape ```json { "success": true, "status_code": 200, "message": "File uploaded successfully", "data": { "object_key": "image/abc123.webp", "url": "https://...", "content_type": "image/webp", "media_type": "image", "provider": "MINIO" } } ``` For videos, response includes Vimeo references: ```json { "success": true, "status_code": 200, "message": "Video uploaded successfully", "data": { "url": "https://vimeo.com/123456789", "content_type": "video/mp4", "media_type": "video", "provider": "VIMEO", "vimeo_id": "123456789", "embed_url": "https://player.vimeo.com/video/123456789" } } ``` --- ## 2) Endpoints Updated to JSON Media Reference Flow These endpoints now support JSON request bodies for media references. ## A) Profile Picture ### `POST /api/v1/user/:id/profile-picture` **Old style:** multipart with `file` **New style:** JSON with uploaded URL #### JSON request body ```json { "profile_picture_url": "https://your-media-url-or-minio-presigned-url" } ``` #### Success response ```json { "success": true, "status_code": 200, "message": "Profile picture URL updated successfully", "data": { "profile_picture_url": "https://your-media-url-or-minio-presigned-url" } } ``` --- ## B) Course Thumbnail ### `POST /api/v1/course-management/courses/:id/thumbnail` **Old style:** multipart with `file` **New style:** JSON with uploaded URL #### JSON request body ```json { "thumbnail_url": "https://your-media-url-or-minio-presigned-url" } ``` #### Success response ```json { "success": true, "message": "Course thumbnail URL updated successfully", "data": { "thumbnail_url": "https://your-media-url-or-minio-presigned-url" } } ``` --- ## C) Sub-course Thumbnail ### `POST /api/v1/course-management/sub-courses/:id/thumbnail` **Old style:** multipart with `file` **New style:** JSON with uploaded URL #### JSON request body ```json { "thumbnail_url": "https://your-media-url-or-minio-presigned-url" } ``` #### Success response ```json { "success": true, "message": "Sub-course thumbnail URL updated successfully", "data": { "thumbnail_url": "https://your-media-url-or-minio-presigned-url" } } ``` --- ## D) Audio Answer Submission ### `POST /api/v1/questions/audio-answer` **Old style:** multipart with `question_id`, `question_set_id`, `file` **New style:** JSON referencing uploaded audio object key #### JSON request body ```json { "question_id": 101, "question_set_id": 5, "object_key": "audio/uuid-audio-file.webm" } ``` #### Success response ```json { "success": true, "status_code": 200, "message": "Audio answer submitted successfully", "data": { "id": 1, "question_id": 101, "question_set_id": 5, "audio_url": "https://...", "created_at": "2026-03-24T10:30:00Z" } } ``` --- ## 3) Recommended Admin Panel Integration Flow For each image/audio/video field: 1. Call `POST /api/v1/files/upload` with `multipart/form-data` 2. Read response `data` - image/audio: use `url` (and keep `object_key` if needed) - video: use `url` / `vimeo_id` / `embed_url` depending on target endpoint 3. Call business endpoint with JSON body using returned media reference --- ## 4) Endpoint List (Quick Reference) - `POST /api/v1/files/upload` (new) - `POST /api/v1/user/:id/profile-picture` (now supports JSON) - `POST /api/v1/course-management/courses/:id/thumbnail` (now supports JSON) - `POST /api/v1/course-management/sub-courses/:id/thumbnail` (now supports JSON) - `POST /api/v1/questions/audio-answer` (now supports JSON) --- ## 5) Backward Compatibility Note Legacy multipart behavior for the updated endpoints is still supported to avoid breaking existing clients during migration. Admin panel should migrate to the new JSON-reference flow for consistency.