Skip to content

Overview

The Asset Library is a centralized system for managing user-uploaded content (images, videos, documents) and AI-generated assets. It provides features for organization (folders, tags), optimization (WebP conversion), and usage tracking.

Core Components

Database Schema

  • CompanyAsset: Stores metadata, S3 keys, and properties of each file.
  • CompanyAssetFolder: Hierarchical folder structure.
  • CompanyAssetTag: Taxonomy for organizing assets.
  • CompanyAssetUsage: Tracks where assets are used (posts, blogs, scripts).
  • PlatformAsset: Links assets to external platform uploads (e.g., WordPress media ID).

Storage

  • S3/R2: All files are stored in an S3-compatible object storage (Cloudflare R2).
  • CDN: Files are served via a CDN for performance.
  • Structure: /{companyId}/assets/{userId}/{timestamp}-{uuid}-{filename}

Asset Service

The AssetService handles business logic:

  • Upload: Validates files, generates keys, creates DB records.
  • Optimization: Automatically converts images to WebP using sharp for better performance.
  • Deduplication: Calculates SHA-256 hash to detect duplicate files.
  • Organization: Manages folders and tags.
  • Usage Tracking: Records where assets are used to prevent accidental deletion of active content.

API Endpoints

Assets

  • POST /api/assets/presigned-url: Get upload URL for client-side upload.
  • POST /api/assets/direct: Direct server-side upload.
  • GET /api/assets: List assets with filtering (folder, type, tags, search).
  • GET /api/assets/:id: Get asset details including lineage.
  • PATCH /api/assets/:id: Update asset metadata (folder, tags, archive).
  • DELETE /api/assets/:id: Delete asset (soft or hard).
  • POST /api/assets/:id/usage: Record asset usage.

Folders

  • POST /api/assets/folders: Create a new folder.
  • GET /api/assets/folders: List folders (hierarchical).
  • DELETE /api/assets/folders/:id: Delete a folder.

Implementation Details

Image Optimization

When an image is uploaded via the /direct endpoint, it is automatically processed:

  1. Original file uploaded to S3.
  2. sharp converts the image to WebP (quality 80).
  3. WebP version uploaded to S3.
  4. DB record updated with the private s3KeyOptimized; authenticated API responses compute a short-lived viewUrlOptimized when needed.

Deduplication

Content hash (SHA-256) is calculated for every file. The system checks for existing non-archived assets with the same hash within the company to prevent duplicate storage.

Security

  • All assets are scoped to companyId.
  • Authenticated preview URLs are short-lived (at most 15 minutes) and are never persisted.
  • Tenant isolation is enforced via getTenantPrisma.

TendSocial Documentation