- Introduced a new endpoint to retrieve CDN URLs for public files, falling back to pre-signed URLs when necessary. - Enhanced caching for file metadata retrieval in GetFileQueryHandler to improve performance. - Updated file handling commands to invalidate relevant caches upon file operations. - Added configuration settings for CDN in appsettings.json to manage CDN behavior. - Implemented new data models for CDN URL responses and integrated them into the API response structure.
139 lines
4.6 KiB
C#
139 lines
4.6 KiB
C#
using StorageService.Domain.SeedWork;
|
|
|
|
namespace StorageService.Domain.AggregatesModel.FolderAggregate;
|
|
|
|
/// <summary>
|
|
/// EN: Folder aggregate root - represents a logical folder for organizing files.
|
|
/// VI: Folder aggregate root - đại diện cho folder logic để tổ chức files.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// EN: CRITICAL: Folders are LOGICAL only (database). Storage uses flat UUID keys.
|
|
/// Folder rename/move is O(1) - only updates database, not storage.
|
|
/// VI: QUAN TRỌNG: Folders chỉ là LOGIC (database). Storage dùng flat UUID keys.
|
|
/// Đổi tên/di chuyển folder là O(1) - chỉ update database, không động storage.
|
|
/// </remarks>
|
|
public class Folder : Entity, IAggregateRoot
|
|
{
|
|
/// <summary>EN: Owner user ID / VI: ID user sở hữu</summary>
|
|
public string UserId { get; private set; } = default!;
|
|
|
|
/// <summary>EN: Parent folder ID (null = root) / VI: ID folder cha (null = root)</summary>
|
|
public Guid? ParentId { get; private set; }
|
|
|
|
/// <summary>EN: Folder name / VI: Tên folder</summary>
|
|
public string Name { get; private set; } = default!;
|
|
|
|
/// <summary>EN: Materialized path (e.g., /parent/child/) / VI: Đường dẫn (vd: /parent/child/)</summary>
|
|
public string Path { get; private set; } = default!;
|
|
|
|
/// <summary>EN: Nesting level (0 = root level) / VI: Cấp độ lồng (0 = cấp root)</summary>
|
|
public int Level { get; private set; }
|
|
|
|
/// <summary>EN: Created timestamp / VI: Thời gian tạo</summary>
|
|
public DateTime CreatedAt { get; private set; }
|
|
|
|
/// <summary>EN: Updated timestamp / VI: Thời gian cập nhật</summary>
|
|
public DateTime UpdatedAt { get; private set; }
|
|
|
|
/// <summary>EN: Soft delete flag / VI: Cờ xóa mềm</summary>
|
|
public bool IsDeleted { get; private set; }
|
|
|
|
/// <summary>EN: Deleted timestamp / VI: Thời gian xóa</summary>
|
|
public DateTime? DeletedAt { get; private set; }
|
|
|
|
// EN: For EF Core / VI: Cho EF Core
|
|
protected Folder() { }
|
|
|
|
/// <summary>
|
|
/// EN: Create a new root folder.
|
|
/// VI: Tạo folder root mới.
|
|
/// </summary>
|
|
public static Folder CreateRoot(string userId, string name)
|
|
{
|
|
return new Folder
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
UserId = userId,
|
|
ParentId = null,
|
|
Name = name,
|
|
Path = $"/{name}/",
|
|
Level = 0,
|
|
CreatedAt = DateTime.UtcNow,
|
|
UpdatedAt = DateTime.UtcNow,
|
|
IsDeleted = false
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// EN: Create a child folder.
|
|
/// VI: Tạo folder con.
|
|
/// </summary>
|
|
public Folder CreateChild(string name)
|
|
{
|
|
return new Folder
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
UserId = UserId,
|
|
ParentId = Id,
|
|
Name = name,
|
|
Path = $"{Path}{name}/",
|
|
Level = Level + 1,
|
|
CreatedAt = DateTime.UtcNow,
|
|
UpdatedAt = DateTime.UtcNow,
|
|
IsDeleted = false
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// EN: Rename folder. O(1) operation - only database update.
|
|
/// VI: Đổi tên folder. O(1) - chỉ update database.
|
|
/// </summary>
|
|
public void Rename(string newName)
|
|
{
|
|
if (IsDeleted)
|
|
throw new InvalidOperationException("Cannot rename deleted folder");
|
|
|
|
var oldPath = Path;
|
|
Name = newName;
|
|
|
|
// EN: Update path - need to update children paths too (via repository)
|
|
// VI: Update path - cần update paths của children (qua repository)
|
|
Path = ParentId == null
|
|
? $"/{newName}/"
|
|
: oldPath.Substring(0, oldPath.LastIndexOf('/', oldPath.Length - 2) + 1) + $"{newName}/";
|
|
|
|
UpdatedAt = DateTime.UtcNow;
|
|
}
|
|
|
|
/// <summary>
|
|
/// EN: Move folder to new parent.
|
|
/// VI: Di chuyển folder sang parent mới.
|
|
/// </summary>
|
|
public void MoveTo(Folder? newParent)
|
|
{
|
|
if (IsDeleted)
|
|
throw new InvalidOperationException("Cannot move deleted folder");
|
|
|
|
if (newParent != null && newParent.UserId != UserId)
|
|
throw new InvalidOperationException("Cannot move folder to different user");
|
|
|
|
ParentId = newParent?.Id;
|
|
Level = newParent == null ? 0 : newParent.Level + 1;
|
|
Path = newParent == null ? $"/{Name}/" : $"{newParent.Path}{Name}/";
|
|
UpdatedAt = DateTime.UtcNow;
|
|
}
|
|
|
|
/// <summary>
|
|
/// EN: Soft delete folder.
|
|
/// VI: Xóa mềm folder.
|
|
/// </summary>
|
|
public void Delete()
|
|
{
|
|
if (IsDeleted)
|
|
return;
|
|
|
|
IsDeleted = true;
|
|
DeletedAt = DateTime.UtcNow;
|
|
}
|
|
}
|