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
sharpfor 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:
- Original file uploaded to S3.
sharpconverts the image to WebP (quality 80).- WebP version uploaded to S3.
- DB record updated with
s3KeyOptimizedandcdnUrlOptimized.
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. - Presigned URLs are short-lived (1 hour).
- Tenant isolation is enforced via
getTenantPrisma.