package models import ( "fmt" "time" "gorm.io/gorm" ) type FileUpload struct { ID uint `json:"id" gorm:"primaryKey"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"` FileName string `json:"file_name" gorm:"not null"` OriginalName string `json:"original_name" gorm:"not null"` FilePath string `json:"file_path" gorm:"not null"` FileSize int64 `json:"file_size" gorm:"not null"` MimeType string `json:"mime_type" gorm:"not null"` Description string `json:"description"` // Foreign Keys UploadedByID uint `json:"uploaded_by_id" gorm:"not null"` ProjectID *uint `json:"project_id"` TaskID *uint `json:"task_id"` // Relationships UploadedBy User `json:"uploaded_by" gorm:"foreignKey:UploadedByID"` Project *Project `json:"project" gorm:"foreignKey:ProjectID"` Task *Task `json:"task" gorm:"foreignKey:TaskID"` } // GetFileExtension returns the file extension func (f *FileUpload) GetFileExtension() string { if len(f.OriginalName) == 0 { return "" } lastDot := -1 for i := len(f.OriginalName) - 1; i >= 0; i-- { if f.OriginalName[i] == '.' { lastDot = i break } } if lastDot == -1 { return "" } return f.OriginalName[lastDot:] } // IsImage checks if the file is an image func (f *FileUpload) IsImage() bool { imageTypes := []string{ "image/jpeg", "image/jpg", "image/png", "image/gif", "image/webp", "image/svg+xml", "image/bmp", "image/tiff", } for _, imgType := range imageTypes { if f.MimeType == imgType { return true } } return false } // IsDocument checks if the file is a document func (f *FileUpload) IsDocument() bool { docTypes := []string{ "application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation", "text/plain", "text/csv", } for _, docType := range docTypes { if f.MimeType == docType { return true } } return false } // FormatFileSize returns a human-readable file size func (f *FileUpload) FormatFileSize() string { const unit = 1024 if f.FileSize < unit { return fmt.Sprintf("%d B", f.FileSize) } div, exp := int64(unit), 0 for n := f.FileSize / unit; n >= unit; n /= unit { div *= unit exp++ } return fmt.Sprintf("%.1f %cB", float64(f.FileSize)/float64(div), "KMGTPE"[exp]) }