using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Lagerbestand.Models; /// /// Represents a file attachment on a Kanban task /// public class KanbanTaskAttachment { public Guid Id { get; set; } = Guid.NewGuid(); public Guid TaskId { get; set; } [Required] [MaxLength(255)] public string FileName { get; set; } = string.Empty; [Required] [MaxLength(100)] public string ContentType { get; set; } = "application/octet-stream"; /// /// File size in bytes /// public long FileSize { get; set; } /// /// Relative path to the file in the storage system (NFS/disk) /// [MaxLength(500)] public string? FilePath { get; set; } /// /// Legacy: File content stored as binary (being migrated to file-based storage) /// [Obsolete("Use FilePath instead. This property is retained for migration purposes only.")] public byte[]? FileContent { get; set; } /// /// User who uploaded the file /// public Guid? UploadedByUserId { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; // Navigation properties public virtual KanbanTask? Task { get; set; } public virtual AppUser? UploadedByUser { get; set; } // Computed properties [NotMapped] public string FileSizeDisplay { get { if (FileSize < 1024) return $"{FileSize} B"; if (FileSize < 1024 * 1024) return $"{FileSize / 1024.0:F1} KB"; return $"{FileSize / (1024.0 * 1024.0):F1} MB"; } } [NotMapped] public string FileIcon { get { var ext = Path.GetExtension(FileName).ToLowerInvariant(); return ext switch { ".pdf" => "📄", ".doc" or ".docx" => "📝", ".xls" or ".xlsx" => "📊", ".ppt" or ".pptx" => "📽️", ".jpg" or ".jpeg" or ".png" or ".gif" or ".webp" => "🖼️", ".zip" or ".rar" or ".7z" => "📦", ".txt" => "📃", _ => "📎" }; } } [NotMapped] public bool IsImage => ContentType.StartsWith("image/"); /// /// Whether the file is stored on disk (vs legacy database storage) /// [NotMapped] public bool IsFileBasedStorage => !string.IsNullOrEmpty(FilePath); /// /// Maximum file size allowed (10 MB) /// public const long MaxFileSize = 10 * 1024 * 1024; }