Files
The File entity represents files stored within the Wrkbelt platform. It supports both public and private files, multiple storage providers, and different upload modes for flexibility.
Schema Definition
type File = {
// Base Properties
_id: string; // MongoDB ObjectId
access_level: FileAccessLevel; // Required, public or private
user_id?: string; // Required for private files
directory: string; // Required, file path
filename: string; // Required, max 255 chars
mime_type: string; // Required, format: type/subtype
size: number; // Required, in bytes
storage_key: string; // Required, unique
storage_provider: StorageProvider; // Required, AWS_S3
storage_location: string; // Required for active files
status: FileStatus; // Required, default: PENDING
upload: UploadContext; // Required, upload metadata
ttl_for_lifecycle?: Date; // Optional, for lifecycle management
metadata: Record<string, unknown>; // Optional custom metadata
// Timestamps
createdAt: Date; // Auto-generated
updatedAt: Date; // Auto-updated
} & BaseEntity;
Field Descriptions
Base Properties
| Field | Type | Required | Unique | Description |
|---|---|---|---|---|
_id | ObjectId | Yes | Yes | Unique identifier for the file |
access_level | FileAccessLevel | Yes | No | Public or private (user or organization) access level |
user_id | ObjectId | For private | No | Owner of private files |
directory | string | Yes | No | File path within storage |
filename | string | Yes | No | Name of the file (max 255 chars) |
mime_type | string | Yes | No | MIME type (e.g., 'image/jpeg') |
size | number | Yes | No | File size in bytes |
storage_key | string | Yes | Yes | Unique identifier in storage system |
storage_provider | StorageProvider | Yes | No | Storage provider (AWS_S3) |
storage_location | string | Conditional | No | URL or path to file (required for active files) |
status | FileStatus | Yes | No | Current state of the file |
ttl_for_lifecycle | Date | No | No | Optional expiration date |
metadata | object | No | No | Custom metadata for the file |
Upload Context
type UploadContext = {
mode: UploadMode; // IMMEDIATE or PRESIGNED
metadata: {
originalName: string; // Original filename
contentType: string; // MIME type
expectedSize: number; // Expected file size
actualSize?: number; // Actual size after upload
uploadStarted: string; // Upload start timestamp
uploadCompleted?: string; // Upload completion timestamp
error?: string; // Error message if failed
};
immediate?: {
received_at: Date; // When file was received
processed_at: Date; // When processing completed
};
presigned?: {
upload_url: string; // Presigned URL
upload_fields: Record<string, string>; // Additional fields
expires_at: Date; // URL expiration
};
};
Enums
FileAccessLevel
enum FileAccessLevel {
PUBLIC = 'public',
PRIVATE_USER = 'private',
PRIVATE_ORGANIZATION = 'organization',
}
FileStatus
enum FileStatus {
PENDING = 'pending', // Initial state for presigned uploads
UPLOADING = 'uploading', // File is being uploaded
VALIDATING = 'validating', // Verification in progress
ACTIVE = 'active', // Successfully uploaded and verified
FAILED = 'failed', // Upload or verification failed
DELETED = 'deleted', // Marked for deletion
}
StorageProvider
enum StorageProvider {
AWS_S3 = 'aws-s3',
}
UploadMode
enum UploadMode {
IMMEDIATE = 'immediate',
PRESIGNED = 'presigned',
}
Relationships
Primary Relationships
-
File → User (Many-to-One, Optional)
- Private files must have an owner
- Referenced via
user_idfield - Public files don't require user association
-
File → Organization (Implicit through context)
- Files are scoped to organizations
- Access controlled through organization membership
- Directory structure may reflect organization
Validation
-
Storage Location
- Must be a valid URL in non-local environments
- Required for ACTIVE files
- Required for UPLOADING files in IMMEDIATE mode
-
MIME Type
- Must match pattern:
^[a-zA-Z0-9]+\/[a-zA-Z0-9.-]+$ - Examples: 'image/jpeg', 'application/pdf'
- Must match pattern:
-
Upload Context
- Required metadata fields based on upload mode
- Timestamps for tracking upload progress
- Mode-specific validation rules
File Lifecycle
-
Creation
// Example of creating a file record
const file = {
access_level: FileAccessLevel.PRIVATE_USER,
user_id: 'user123',
directory: 'documents/2024',
filename: 'report.pdf',
mime_type: 'application/pdf',
size: 1024567,
storage_key: 'unique-storage-key',
storage_provider: StorageProvider.AWS_S3,
status: FileStatus.PENDING,
upload: {
mode: UploadMode.PRESIGNED,
metadata: {
originalName: 'report.pdf',
contentType: 'application/pdf',
expectedSize: 1024567,
uploadStarted: new Date().toISOString(),
},
},
}; -
Status Transitions
// Example of updating file status
await File.updateOne(
{ _id: fileId },
{
$set: {
status: FileStatus.ACTIVE,
storage_location: 'https://storage.example.com/file.pdf',
},
}
);
Security Considerations
-
Access Control
- Private files require user authentication
- Public files are accessible through storage URL
- File operations require appropriate permissions
-
Upload Security
- File size limits enforced
- MIME type validation
- Malware scanning (if configured)
- Secure URL generation for presigned uploads
-
Storage Security
- Encrypted storage (provider-dependent)
- Secure access credentials
- TTL-based lifecycle management
- Proper file deletion procedures
Performance Considerations
-
Indexes
- Compound index on
{ access_level: 1, status: 1 } - Single indexes on frequently queried fields
- TTL index for lifecycle management
- Compound index on
-
Upload Modes
- IMMEDIATE for smaller files
- PRESIGNED for large files
- Progress tracking for both modes
-
Storage Optimization
- File deduplication (if implemented)
- Compression (where appropriate)
- CDN integration for public files