Files
starr-philproperties/controllers/admin/documentation/assets.md
T
2026-05-09 22:17:24 +08:00

12 KiB

Assets Controller Documentation

File: controllers/admin/assets.controller.js
Base URL: /api/admin/assets
Guards: authenticate → requireAdmin() → adminLimiter


Table of Contents


Get All Assets

GET /api/admin/assets

Returns a paginated list of non-deleted assets with optional filtering.

Query Parameters

Parameter Type Required Description
page number No Page number. Default: 1
limit number No Records per page. Default: 20
file_type string No Filter by type: image, video, document, other
owner_type string No Filter by owner type e.g. User, Course
owner_id number No Filter by owner ID
uploadedBy number No Filter by uploader user ID
is_public boolean No Filter by visibility: true or false
resolution string No Filter by resolution e.g. 1080p, 720p
search string No Search by display_name, original_name, description
sort_by string No Column to sort by. Default: createdAt
sort_dir string No Sort direction: ASC or DESC. Default: DESC

Response 200

{
  "status": "success",
  "message": "Assets retrieved.",
  "data": {
    "rows": [...],
    "pagination": {
      "total": 100,
      "page": 1,
      "limit": 20,
      "totalPages": 5
    }
  }
}

Get Single Asset

GET /api/admin/assets/:assetId

Returns a single non-deleted asset by ID.

Path Parameters

Parameter Type Required Description
assetId number Yes Asset ID

Response 200

{
  "status": "success",
  "message": "Asset found.",
  "data": {
    "asset_id": 1,
    "uuid": "550e8400-e29b-41d4-a716-446655440000",
    "original_name": "intro.mp4",
    "display_name": "Course Intro Video",
    "file_url": "/uploads/intro.mp4",
    "file_size": 104857600,
    "mime_type": "video/mp4",
    "extension": "mp4",
    "checksum": "a3f5...",
    "file_type": "video",
    "width": 1920,
    "height": 1080,
    "duration": 120.5,
    "resolution": "1080p",
    "frame_rate": 29.97,
    "bitrate": 8000000,
    "video_codec": "H.264",
    "audio_codec": "AAC",
    "thumbnail_url": "/uploads/thumbnails/intro.jpg",
    "description": "Introduction to the course.",
    "storage_provider": "local",
    "storage_bucket": null,
    "storage_key": "intro.mp4",
    "is_public": true,
    "access_level": "public",
    "owner_type": "Course",
    "owner_id": 3,
    "uploadedBy": 1,
    "deletedBy": null,
    "createdAt": "2025-01-01T00:00:00.000Z",
    "updatedAt": "2025-01-01T00:00:00.000Z",
    "deletedAt": null
  }
}

Response 404

{
  "status": "error",
  "message": "Asset not found."
}

Upload Asset

POST /api/admin/assets/upload

Uploads a new asset. Expects multipart/form-data.
Video metadata (width, height, duration, etc.) should be extracted via ffprobe server-side or passed from the client.
resolution is auto-derived from width and height — do not pass it manually.

Request multipart/form-data

Field Type Required Description
file File Yes The file to upload
uploadedBy number Yes User ID of the uploader
display_name string No Display name shown on platform. Defaults to filename
description string No Description of the asset
owner_type string No Owning entity type e.g. Course, User
owner_id number No Owning entity ID
is_public boolean No Whether asset is publicly accessible. Default: false
access_level string No public, private, restricted. Default: private
storage_provider string No local, s3, gcs, cloudinary, chibisafe, other. Default: local
storage_bucket string No Bucket/container name for cloud storage
storage_key string No Object key/path in bucket
file_url string No* Required for non-local storage providers
width number No Video/image width in px
height number No Video/image height in px
duration number No Video duration in seconds
frame_rate number No Video frame rate in fps
bitrate number No Video bitrate in bps
video_codec string No Video codec e.g. H.264, H.265
audio_codec string No Audio codec e.g. AAC, MP3
thumbnail_url string No URL of the video/document preview thumbnail

Resolution Auto-Derivation

Height (px) Derived Resolution
≥ 2160 4K
≥ 1440 1440p
≥ 1080 1080p
≥ 720 720p
≥ 480 480p
≥ 360 360p
≥ 240 240p
Other {width}x{height}

Response 201

{
  "status": "success",
  "message": "Asset uploaded.",
  "data": { ...asset }
}

Response 400

{
  "status": "error",
  "message": "No file uploaded."
}

Update Asset Metadata

PUT /api/admin/assets/:assetId

Updates metadata of an existing asset. File replacement is not supported — upload a new asset instead.
resolution is auto-re-derived if width or height is updated.

Path Parameters

Parameter Type Required Description
assetId number Yes Asset ID

Request Body application/json

Field Type Required Description
display_name string No Updated display name
description string No Updated description
owner_type string No Updated owner type
owner_id number No Updated owner ID
is_public boolean No Updated visibility
access_level string No Updated access level
thumbnail_url string No Updated thumbnail URL
width number No Updated width — re-derives resolution
height number No Updated height — re-derives resolution
duration number No Updated duration
frame_rate number No Updated frame rate
bitrate number No Updated bitrate
video_codec string No Updated video codec
audio_codec string No Updated audio codec

Response 200

{
  "status": "success",
  "message": "Asset updated.",
  "data": { ...asset }
}

Update Thumbnail

PATCH /api/admin/assets/:assetId/thumbnail

Updates only the thumbnail of an asset. Useful for video platforms where users frequently change the video cover independently.

Path Parameters

Parameter Type Required Description
assetId number Yes Asset ID

Request Body application/json

Field Type Required Description
thumbnail_url string Yes New thumbnail URL

Response 200

{
  "status": "success",
  "message": "Thumbnail updated.",
  "data": { ...asset }
}

Response 400

{
  "status": "error",
  "message": "thumbnail_url is required."
}

Delete Asset

DELETE /api/admin/assets/:assetId

Soft deletes a single asset by setting deletedAt and deletedBy.

Path Parameters

Parameter Type Required Description
assetId number Yes Asset ID

Request Body application/json

Field Type Required Description
deletedBy number No User ID of who deleted the asset

Response 200

{
  "status": "success",
  "message": "Asset deleted."
}

Bulk Delete Assets

DELETE /api/admin/assets/bulk

Soft deletes multiple assets at once.

Request Body application/json

Field Type Required Description
ids number[] Yes Array of asset IDs to delete
deletedBy number No User ID of who deleted the assets

Response 200

{
  "status": "success",
  "message": "3 asset(s) deleted."
}

Response 400

{
  "status": "error",
  "message": "ids must be a non-empty array."
}

Restore Asset

PATCH /api/admin/assets/:assetId/restore

Restores a soft-deleted asset by clearing deletedAt and deletedBy.

Path Parameters

Parameter Type Required Description
assetId number Yes Asset ID

Response 200

{
  "status": "success",
  "message": "Asset restored.",
  "data": { ...asset }
}

Response 404

{
  "status": "error",
  "message": "Asset not found or not deleted."
}

Error Responses

All endpoints return the following on server error:

{
  "status": "error",
  "message": "Internal server error."
}

File Size Limits

Type Max Size
Images 10 GB
Videos 10 GB
Documents 10 GB

Limit is applied at the multer middleware level. Adjust in assets.routes.js if needed.


Notes

  • File replacement is not supported. To replace a file, delete the old asset and upload a new one.
  • Checksum (SHA-256) is computed on upload for duplicate detection.
  • Polymorphic ownership via owner_type + owner_id allows any entity (Course, User, Post, etc.) to own assets without a direct foreign key.
  • Resolution is always auto-derived from width and height — never set manually.
  • Soft delete sets deletedAt timestamp. Assets are excluded from all queries unless explicitly queried with paranoid: false.