package models import ( "time" "github.com/google/uuid" ) // ── Enums ───────────────────────────────────────────────────────────────────── type FileKind string const ( FileKindVideo FileKind = "Video" FileKindImage FileKind = "Image" FileKindAudio FileKind = "Audio" FileKindVoiceover FileKind = "Voiceover" FileKindDocument FileKind = "Document" FileKindOther FileKind = "Other" ) type FolderKind string const ( FolderKindSystem FolderKind = "System" FolderKindUser FolderKind = "User" FolderKindShared FolderKind = "Shared" FolderKindTenant FolderKind = "Tenant" ) type UploadStatus string const ( UploadStatusPending UploadStatus = "Pending" UploadStatusUploading UploadStatus = "Uploading" UploadStatusProcessing UploadStatus = "Processing" UploadStatusReady UploadStatus = "Ready" UploadStatusFailed UploadStatus = "Failed" UploadStatusQuarantined UploadStatus = "Quarantined" ) type CleanupEntityType string const ( CleanupEntityExport CleanupEntityType = "Export" CleanupEntityTempRenderFolder CleanupEntityType = "TempRenderFolder" CleanupEntityOrphanedFile CleanupEntityType = "OrphanedFile" CleanupEntityUnusedUpload CleanupEntityType = "UnusedUpload" CleanupEntitySnapshotExpired CleanupEntityType = "SnapshotExpired" ) type CleanupStatus string const ( CleanupStatusScheduled CleanupStatus = "Scheduled" CleanupStatusNotified CleanupStatus = "Notified" CleanupStatusProcessing CleanupStatus = "Processing" CleanupStatusDone CleanupStatus = "Done" CleanupStatusSkipped CleanupStatus = "Skipped" CleanupStatusFailed CleanupStatus = "Failed" ) // ── Domain ──────────────────────────────────────────────────────────────────── type UserFolder struct { ID uuid.UUID `json:"id"` TenantID uuid.UUID `json:"tenant_id"` UserID uuid.UUID `json:"user_id"` Name string `json:"name"` FolderType FolderKind `json:"folder_type"` ParentFolderID *uuid.UUID `json:"parent_folder_id,omitempty"` FileCount int `json:"file_count"` TotalSizeBytes int64 `json:"total_size_bytes"` Sort int `json:"sort"` IsShared bool `json:"is_shared"` ShareToken *string `json:"share_token,omitempty"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` DeletedAt *time.Time `json:"deleted_at,omitempty"` } type UserFile struct { ID uuid.UUID `json:"id"` TenantID uuid.UUID `json:"tenant_id"` UserID uuid.UUID `json:"user_id"` UserFolderID *uuid.UUID `json:"user_folder_id,omitempty"` Name string `json:"name"` OriginalFilename *string `json:"original_filename,omitempty"` FileExtension *string `json:"file_extension,omitempty"` MimeType *string `json:"mime_type,omitempty"` FileType FileKind `json:"file_type"` MinioBucket string `json:"minio_bucket"` MinioKey string `json:"minio_key"` CdnURL *string `json:"cdn_url,omitempty"` FileAddress string `json:"file_address"` SizeBytes int64 `json:"size_bytes"` Md5Hash *string `json:"md5_hash,omitempty"` Sha256Hash *string `json:"sha256_hash,omitempty"` DurationSec *float64 `json:"duration_sec,omitempty"` Width *int `json:"width,omitempty"` Height *int `json:"height,omitempty"` Fps *float64 `json:"fps,omitempty"` BitrateKbps *int `json:"bitrate_kbps,omitempty"` Codec *string `json:"codec,omitempty"` HasAudio *bool `json:"has_audio,omitempty"` HasVideo *bool `json:"has_video,omitempty"` ThumbnailURL *string `json:"thumbnail_url,omitempty"` WaveformData *string `json:"waveform_data,omitempty"` UploadStatus UploadStatus `json:"upload_status"` UploadProgress int `json:"upload_progress"` Source *string `json:"source,omitempty"` ExportID *uuid.UUID `json:"export_id,omitempty"` ParentFileID *uuid.UUID `json:"parent_file_id,omitempty"` LastUsedAt *time.Time `json:"last_used_at,omitempty"` UseCount int `json:"use_count"` IsPublic bool `json:"is_public"` ShareToken *string `json:"share_token,omitempty"` Metadata string `json:"metadata"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` DeletedAt *time.Time `json:"deleted_at,omitempty"` } type StorageQuota struct { UserID uuid.UUID `json:"user_id"` TenantID uuid.UUID `json:"tenant_id"` PlanQuotaBytes int64 `json:"plan_quota_bytes"` BonusQuotaBytes int64 `json:"bonus_quota_bytes"` UsedBytes int64 `json:"used_bytes"` VideoCount int `json:"video_count"` ImageCount int `json:"image_count"` AudioCount int `json:"audio_count"` VideoBytes int64 `json:"video_bytes"` ImageBytes int64 `json:"image_bytes"` AudioBytes int64 `json:"audio_bytes"` Last90PctNotifiedAt *time.Time `json:"last_90pct_notified_at,omitempty"` Last100PctNotifiedAt *time.Time `json:"last_100pct_notified_at,omitempty"` UpdatedAt time.Time `json:"updated_at"` } type UploadSession struct { ID uuid.UUID `json:"id"` TenantID uuid.UUID `json:"tenant_id"` UserID uuid.UUID `json:"user_id"` MinioBucket string `json:"minio_bucket"` MinioKey string `json:"minio_key"` MinioUploadID string `json:"minio_upload_id"` Filename string `json:"filename"` MimeType *string `json:"mime_type,omitempty"` TotalSizeBytes int64 `json:"total_size_bytes"` ChunksReceived int `json:"chunks_received"` BytesReceived int64 `json:"bytes_received"` ChunkSizeBytes int `json:"chunk_size_bytes"` TargetFolderID *uuid.UUID `json:"target_folder_id,omitempty"` TargetFileID *uuid.UUID `json:"target_file_id,omitempty"` Status UploadStatus `json:"status"` ErrorMessage *string `json:"error_message,omitempty"` ExpiresAt time.Time `json:"expires_at"` CompletedAt *time.Time `json:"completed_at,omitempty"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } type MinioBucket struct { ID uuid.UUID `json:"id"` Name string `json:"name"` Region string `json:"region"` Endpoint string `json:"endpoint"` Purpose string `json:"purpose"` IsPublic bool `json:"is_public"` CdnBaseURL *string `json:"cdn_base_url,omitempty"` IsActive bool `json:"is_active"` CreatedAt time.Time `json:"created_at"` } // ── Request / Response ──────────────────────────────────────────────────────── type CreateFolderRequest struct { Name string `json:"name" binding:"required"` ParentFolderID *uuid.UUID `json:"parent_folder_id"` } type MoveFolderRequest struct { ParentFolderID *uuid.UUID `json:"parent_folder_id"` } type RenameFolderRequest struct { Name string `json:"name" binding:"required"` } type InitiateUploadRequest struct { Filename string `json:"filename" binding:"required"` MimeType *string `json:"mime_type"` TotalSizeBytes int64 `json:"total_size_bytes" binding:"required,min=1"` ChunkSizeBytes int `json:"chunk_size_bytes"` TargetFolderID *uuid.UUID `json:"target_folder_id"` } type PresignedUploadRequest struct { Filename string `json:"filename" binding:"required"` MimeType *string `json:"mime_type"` SizeBytes int64 `json:"size_bytes" binding:"required,min=1"` TargetFolderID *uuid.UUID `json:"target_folder_id"` } type PresignedUploadResponse struct { UploadURL string `json:"upload_url"` FileID uuid.UUID `json:"file_id"` ExpiresAt time.Time `json:"expires_at"` } type FileListRequest struct { Page int `form:"page,default=1"` PageSize int `form:"page_size,default=20"` FolderID *uuid.UUID `form:"folder_id"` FileType *FileKind `form:"file_type"` Search *string `form:"search"` } type PagedResponse[T any] struct { Items []T `json:"items"` Meta PaginationMeta `json:"meta"` } type PaginationMeta struct { Page int `json:"page"` PageSize int `json:"page_size"` Total int64 `json:"total"` TotalPages int `json:"total_pages"` } type APIError struct { Code string `json:"code"` Message string `json:"message"` } type ErrorResponse struct { Error APIError `json:"error"` } // ── JWT Claims ──────────────────────────────────────────────────────────────── type Claims struct { Sub string `json:"sub"` TenantID string `json:"tenant_id"` IsAdmin bool `json:"is_admin"` }