150 lines
7.0 KiB
Go
150 lines
7.0 KiB
Go
package filemanager
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
"wucher/internal/shared/pkg/uuidv7"
|
|
)
|
|
|
|
const (
|
|
FileStatusUploaded = "uploaded"
|
|
FileStatusProcessing = "processing"
|
|
FileStatusValidated = "validated"
|
|
FileStatusFailed = "failed"
|
|
FileStatusReady = "ready"
|
|
FileStatusTrashed = "trashed"
|
|
|
|
FileLifecycleStatusTemp = "temp"
|
|
FileLifecycleStatusDraft = "draft"
|
|
FileLifecycleStatusActive = "active"
|
|
FileLifecycleStatusFinal = "final"
|
|
FileLifecycleStatusOrphanPending = "orphan_pending"
|
|
FileLifecycleStatusDeleted = "deleted"
|
|
)
|
|
|
|
type File struct {
|
|
ID []byte `gorm:"type:binary(16);primaryKey;column:id"`
|
|
FolderID []byte `gorm:"type:binary(16);not null;column:folder_id;index:idx_file_files_folder_active,priority:1;index:uq_file_files_folder_name_slot,priority:1"`
|
|
Name string `gorm:"type:varchar(255);not null;column:name"`
|
|
NameNormalized string `gorm:"type:varchar(255);not null;column:name_normalized;index:uq_file_files_folder_name_slot,priority:2"`
|
|
Extension string `gorm:"type:varchar(32);column:extension"`
|
|
SizeBytes int64 `gorm:"type:bigint unsigned;not null;default:0;column:size_bytes"`
|
|
MimeType string `gorm:"type:varchar(255);not null;column:mime_type"`
|
|
Bucket string `gorm:"type:varchar(128);not null;column:bucket"`
|
|
ObjectKey string `gorm:"type:varchar(512);not null;column:object_key;uniqueIndex:uq_file_files_object_key"`
|
|
ObjectVersion string `gorm:"type:varchar(128);column:object_version"`
|
|
ETag string `gorm:"type:varchar(128);column:etag"`
|
|
ThumbnailMimeType *string `gorm:"type:varchar(255);column:thumbnail_mime_type"`
|
|
ThumbnailSizeBytes int64 `gorm:"type:bigint unsigned;column:thumbnail_size_bytes"`
|
|
ThumbnailBucket *string `gorm:"type:varchar(128);column:thumbnail_bucket"`
|
|
ThumbnailObjectKey *string `gorm:"type:varchar(512);column:thumbnail_object_key;uniqueIndex:uq_file_files_thumbnail_object_key"`
|
|
ThumbnailObjectVersion *string `gorm:"type:varchar(128);column:thumbnail_object_version"`
|
|
ThumbnailETag *string `gorm:"type:varchar(128);column:thumbnail_etag"`
|
|
PreviewMimeType *string `gorm:"type:varchar(255);column:preview_mime_type"`
|
|
PreviewSizeBytes int64 `gorm:"type:bigint unsigned;column:preview_size_bytes"`
|
|
PreviewBucket *string `gorm:"type:varchar(128);column:preview_bucket"`
|
|
PreviewObjectKey *string `gorm:"type:varchar(512);column:preview_object_key;uniqueIndex:uq_file_files_preview_object_key"`
|
|
PreviewObjectVersion *string `gorm:"type:varchar(128);column:preview_object_version"`
|
|
PreviewETag *string `gorm:"type:varchar(128);column:preview_etag"`
|
|
ChecksumSHA256 string `gorm:"type:char(64);column:checksum_sha256"`
|
|
IsTemplate bool `gorm:"column:is_template;not null;default:false"`
|
|
TemplateUUID []byte `gorm:"type:binary(16);column:template_uuid;index:idx_file_files_template_takeover,priority:1"`
|
|
TakeoverID []byte `gorm:"type:binary(16);column:takeover_id;index:idx_file_files_template_takeover,priority:2"`
|
|
Status string `gorm:"type:varchar(32);not null;default:'uploaded';column:status;index:idx_file_files_status_updated,priority:1"`
|
|
ProcessingStartedAt *time.Time `gorm:"column:processing_started_at"`
|
|
ProcessedAt *time.Time `gorm:"column:processed_at"`
|
|
ValidatedAt *time.Time `gorm:"column:validated_at"`
|
|
FailedAt *time.Time `gorm:"column:failed_at"`
|
|
FailureReason string `gorm:"type:text;column:failure_reason"`
|
|
UploadError string `gorm:"type:text;column:upload_error"`
|
|
NameSlot string `gorm:"type:char(36);not null;default:'live';column:name_slot;index:uq_file_files_folder_name_slot,priority:3"`
|
|
CreatedAt time.Time `gorm:"column:created_at"`
|
|
CreatedBy []byte `gorm:"type:binary(16);column:created_by"`
|
|
UpdatedAt time.Time `gorm:"column:updated_at;index:idx_file_files_status_updated,priority:2"`
|
|
UpdatedBy []byte `gorm:"type:binary(16);column:updated_by"`
|
|
DeletedAt *time.Time `gorm:"column:deleted_at;index:idx_file_files_folder_active,priority:2"`
|
|
DeletedBy []byte `gorm:"type:binary(16);column:deleted_by"`
|
|
TrashedAt *time.Time `gorm:"column:trashed_at"`
|
|
PurgeAt *time.Time `gorm:"column:purge_at;index:idx_file_files_purge_at"`
|
|
LifecycleStatus string `gorm:"type:varchar(32);not null;default:'temp';column:lifecycle_status;index:idx_file_files_lifecycle_status_orphaned,priority:1"`
|
|
AttachedAt *time.Time `gorm:"column:attached_at"`
|
|
OrphanedAt *time.Time `gorm:"column:orphaned_at;index:idx_file_files_lifecycle_status_orphaned,priority:2"`
|
|
LifecycleDeletedAt *time.Time `gorm:"column:lifecycle_deleted_at"`
|
|
WOPILockID string `gorm:"type:varchar(128);column:wopi_lock_id"`
|
|
WOPILockJTI string `gorm:"type:varchar(128);column:wopi_lock_jti"`
|
|
WOPILockedAt *time.Time `gorm:"column:wopi_locked_at"`
|
|
WOPILockExpiresAt *time.Time `gorm:"column:wopi_lock_expires_at"`
|
|
|
|
Folder *Folder `gorm:"foreignKey:FolderID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:RESTRICT"`
|
|
}
|
|
|
|
func (File) TableName() string { return "file_files" }
|
|
|
|
func (f *File) BeforeCreate(tx *gorm.DB) error {
|
|
if len(f.ID) == 0 {
|
|
f.ID = uuidv7.MustBytes()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func NormalizeFileStatus(status string) string {
|
|
s := strings.ToLower(strings.TrimSpace(status))
|
|
switch s {
|
|
case "pending":
|
|
return FileStatusUploaded
|
|
case "uploading":
|
|
return FileStatusProcessing
|
|
default:
|
|
return s
|
|
}
|
|
}
|
|
|
|
func IsKnownFileStatus(status string) bool {
|
|
switch NormalizeFileStatus(status) {
|
|
case FileStatusUploaded, FileStatusProcessing, FileStatusValidated, FileStatusFailed, FileStatusReady, FileStatusTrashed:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func CanTransitionFileStatus(fromStatus, toStatus string) bool {
|
|
from := NormalizeFileStatus(fromStatus)
|
|
to := NormalizeFileStatus(toStatus)
|
|
|
|
switch from {
|
|
case FileStatusUploaded:
|
|
return to == FileStatusProcessing || to == FileStatusFailed
|
|
case FileStatusProcessing:
|
|
return to == FileStatusValidated || to == FileStatusFailed
|
|
case FileStatusValidated:
|
|
return to == FileStatusReady || to == FileStatusFailed
|
|
case FileStatusReady:
|
|
return to == FileStatusTrashed
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func NormalizeFileLifecycleStatus(status string) string {
|
|
s := strings.ToLower(strings.TrimSpace(status))
|
|
switch s {
|
|
case "":
|
|
return FileLifecycleStatusTemp
|
|
default:
|
|
return s
|
|
}
|
|
}
|
|
|
|
func IsKnownFileLifecycleStatus(status string) bool {
|
|
switch NormalizeFileLifecycleStatus(status) {
|
|
case FileLifecycleStatusTemp, FileLifecycleStatusDraft, FileLifecycleStatusActive, FileLifecycleStatusFinal, FileLifecycleStatusOrphanPending, FileLifecycleStatusDeleted:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|