using System.ComponentModel.DataAnnotations; namespace Domain.Entities.Chat; /// /// 채팅 제재 (개미투자 D2) — RoomKey NULL 은 전체 룸 제재, ExpiresAt NULL 은 무기한. /// 발언(SendMessage)만 차단하고 읽기는 허용한다. /// public class ChatBan { [Key] public int ID { get; private set; } /// 제재 대상 회원 (FK Member) public int MemberID { get; private set; } /// 제재 룸 키 — NULL 이면 전체 룸 public string? RoomKey { get; private set; } /// 제재 사유 public string Reason { get; private set; } = default!; /// 만료 일시 (UTC) — NULL 이면 무기한 public DateTime? ExpiresAt { get; private set; } /// 제재 등록자 (Admin 계정 표시명) public string CreatedBy { get; private set; } = default!; public DateTime CreatedAt { get; private set; } = DateTime.UtcNow; private ChatBan() { } public static ChatBan Create(int memberID, string? roomKey, string reason, DateTime? expiresAt, string createdBy) { if (memberID <= 0) { throw new ArgumentOutOfRangeException(nameof(memberID)); } if (string.IsNullOrWhiteSpace(reason)) { throw new ArgumentException("reason required", nameof(reason)); } if (string.IsNullOrWhiteSpace(createdBy)) { throw new ArgumentException("createdBy required", nameof(createdBy)); } return new ChatBan { MemberID = memberID, RoomKey = string.IsNullOrWhiteSpace(roomKey) ? null : roomKey.Trim(), Reason = reason.Trim(), ExpiresAt = expiresAt, CreatedBy = createdBy.Trim() }; } /// 현재 시각 기준 유효한 제재인지 public bool IsActiveAt(DateTime nowUtc) => ExpiresAt is null || ExpiresAt > nowUtc; /// 제재 즉시 해제 — 만료 시각을 현재로 당김 (이력 보존) public void Lift(DateTime nowUtc) { if (!IsActiveAt(nowUtc)) { return; } ExpiresAt = nowUtc; } }