using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Domain.Entities.Members; namespace Domain.Entities.Donations; /// /// 크리에이터가 직접 설정한 채널 전용 칭호 (투네이션 방식). /// 누적 후원 금액을 달성한 후원자에게 자동 부여됨. /// public sealed class ChannelTitle { [ForeignKey(nameof(ChannelID))] public Channel Channel { get; private set; } = null!; [Key] public int ID { get; private set; } public int ChannelID { get; private set; } public string Name { get; private set; } = default!; public string? Description { get; private set; } public long MinAmount { get; private set; } public string Color { get; private set; } = "#A855F7"; public string? IconUrl { get; private set; } public int SortOrder { get; private set; } public bool IsActive { get; private set; } = true; public DateTime? UpdatedAt { get; private set; } public DateTime CreatedAt { get; private set; } = DateTime.UtcNow; private ChannelTitle() { } private ChannelTitle(int channelID, string name, long minAmount, string color) { if (channelID <= 0) { throw new ArgumentOutOfRangeException(nameof(channelID)); } if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("Name is required.", nameof(name)); } if (name.Length > 20) { throw new ArgumentOutOfRangeException(nameof(name)); } if (minAmount < 0) { throw new ArgumentOutOfRangeException(nameof(minAmount)); } ChannelID = channelID; Name = name; MinAmount = minAmount; Color = string.IsNullOrWhiteSpace(color) ? "#A855F7" : color; } public static ChannelTitle Create(int channelID, string name, long minAmount, string color) { return new(channelID, name, minAmount, color); } public void Update(string name, string? description, long minAmount, string color, string? iconUrl, bool isActive) { if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("Name is required.", nameof(name)); } if (name.Length > 20) { throw new ArgumentOutOfRangeException(nameof(name)); } if (description != null && description.Length > 100) { throw new ArgumentOutOfRangeException(nameof(description)); } if (minAmount < 0) { throw new ArgumentOutOfRangeException(nameof(minAmount)); } Name = name; Description = description; MinAmount = minAmount; Color = string.IsNullOrWhiteSpace(color) ? Color : color; IconUrl = iconUrl; IsActive = isActive; UpdatedAt = DateTime.UtcNow; } public void SetOrder(int order) { SortOrder = order; UpdatedAt = DateTime.UtcNow; } }