Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/LMendoza70/SSA/llms.txt

Use this file to discover all available pages before exploring further.

The Multimedia module provides a single, centralized library for every file used across the platform. Rather than embedding or uploading files independently for each piece of content, administrators upload files once and reference them by ID in any number of news articles, infographics, documents, campaigns, or other content types. This architecture guarantees that the same image is never stored twice, keeps storage costs predictable, and makes it trivial to update or replace a file in one place and have that change reflected everywhere it is referenced.

Supported File Types

The module accepts four categories of media. Files outside these types or exceeding the size limits are rejected at upload time with a 400 Bad Request response.
TypeFormatsMax Size
ImageJPEG, PNG, WebP, SVG10 MB
VideoMP4, WebM500 MB
DocumentPDF50 MB
AudioMP3, WAV, OGG50 MB

Deduplication

Before persisting any uploaded file, the module runs a content-based deduplication check. This prevents identical files from consuming additional storage and ensures a single canonical MediaAsset record exists for each unique file.
1

Hash the file

The module computes an SHA-256 hash of the raw file bytes immediately after receiving the multipart upload. This hash uniquely identifies the file’s contents, independent of its name or upload timestamp.
2

Query for an existing asset

The hash is used to query the MediaAsset table for an existing record with a matching hash value. Because hash carries a unique constraint, at most one record can match.
3

Return the existing asset if found

If a matching MediaAsset is found, the module returns that existing record immediately. The file is not written to storage again. The caller receives the same response they would have received from a fresh upload.
4

Store and record if new

If no match is found, the file is handed off to the StorageProvider abstraction for persistence (local filesystem in development; S3, Azure Blob Storage, or GCS in production). A new MediaAsset record is then created in the database with the computed hash, resolved URL, and file metadata.
The StorageProvider abstraction means the deduplication logic, the API layer, and all content modules remain completely decoupled from the underlying storage backend. Migrating from local file storage to Amazon S3 requires no changes outside the provider implementation.

MediaAsset Schema

The MediaAsset model is the canonical database representation of every uploaded file. All content types that reference media store an array of MediaAsset IDs rather than raw file paths.
model MediaAsset {
  id           String    @id @default(uuid())
  filename     String
  originalName String
  mimeType     String
  size         Int
  hash         String    @unique
  url          String
  type         MediaType // IMAGE | VIDEO | DOCUMENT | AUDIO
  altText      String?
  createdAt    DateTime  @default(now())
  updatedAt    DateTime  @updatedAt
  deletedAt    DateTime?
  createdBy    String?
}
The hash field carries a database-level @unique constraint, which acts as the enforcement mechanism for deduplication even in concurrent upload scenarios. The url field holds the fully-qualified, publicly accessible URL returned by the StorageProvider after the file is written.

API Reference

The Multimedia module exposes a focused set of REST endpoints for listing, uploading, retrieving, and deleting media assets.
GET    /multimedia?type=image&page=1&limit=20
POST   /multimedia/upload     (multipart/form-data)
GET    /multimedia/:id
DELETE /multimedia/:id

Upload a File

Files are uploaded as multipart/form-data. The file part is required; altText is optional but strongly recommended for images to meet WCAG accessibility requirements.
curl -X POST http://localhost:3000/multimedia/upload \
  -H "Authorization: Bearer <token>" \
  -F "file=@image.jpg" \
  -F "altText=Campaña de vacunación 2025"
A successful upload returns a 201 Created response with the full MediaAsset object:
{
  "id": "uuid",
  "filename": "image-abc123.jpg",
  "originalName": "image.jpg",
  "mimeType": "image/jpeg",
  "size": 245678,
  "url": "https://storage.example.com/uploads/image-abc123.jpg",
  "type": "IMAGE",
  "altText": "Campaña de vacunación 2025"
}
If the file has been uploaded before, the module returns the existing MediaAsset record with a 200 OK status instead of 201 Created, so callers can detect deduplication by inspecting the response code.

Referencing Media in Content

To attach one or more media assets to a content item, include a mediaIds array in the create or update request body. The CMS module resolves the IDs to full MediaAsset objects when returning content detail responses.
{
  "title": "Mi noticia",
  "mediaIds": ["uuid-of-media-asset"]
}
This association model means a single infographic image, for example, can be attached to a campaign, a news article, and a disease entry simultaneously — with no file duplication and a single point of update.
Media assets are never deleted automatically. To remove a file, explicitly call DELETE /multimedia/:id. Assets that are referenced by one or more PUBLISHED content items cannot be deleted until all referencing content has been moved to ARCHIVED status. Attempting to delete a protected asset returns 409 Conflict.
Deleting a MediaAsset permanently removes the file from the StorageProvider. This action is irreversible. Assets in DRAFT content can be deleted, but consider whether the same file may be reused in future content before confirming the deletion.

Build docs developers (and LLMs) love