ChatBan.cs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. using System.ComponentModel.DataAnnotations;
  2. namespace Domain.Entities.Chat;
  3. /// <summary>
  4. /// 채팅 제재 (개미투자 D2) — RoomKey NULL 은 전체 룸 제재, ExpiresAt NULL 은 무기한.
  5. /// 발언(SendMessage)만 차단하고 읽기는 허용한다.
  6. /// </summary>
  7. public class ChatBan
  8. {
  9. [Key]
  10. public int ID { get; private set; }
  11. /// <summary>제재 대상 회원 (FK Member)</summary>
  12. public int MemberID { get; private set; }
  13. /// <summary>제재 룸 키 — NULL 이면 전체 룸</summary>
  14. public string? RoomKey { get; private set; }
  15. /// <summary>제재 사유</summary>
  16. public string Reason { get; private set; } = default!;
  17. /// <summary>만료 일시 (UTC) — NULL 이면 무기한</summary>
  18. public DateTime? ExpiresAt { get; private set; }
  19. /// <summary>제재 등록자 (Admin 계정 표시명)</summary>
  20. public string CreatedBy { get; private set; } = default!;
  21. public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
  22. private ChatBan() { }
  23. public static ChatBan Create(int memberID, string? roomKey, string reason, DateTime? expiresAt, string createdBy)
  24. {
  25. if (memberID <= 0)
  26. {
  27. throw new ArgumentOutOfRangeException(nameof(memberID));
  28. }
  29. if (string.IsNullOrWhiteSpace(reason))
  30. {
  31. throw new ArgumentException("reason required", nameof(reason));
  32. }
  33. if (string.IsNullOrWhiteSpace(createdBy))
  34. {
  35. throw new ArgumentException("createdBy required", nameof(createdBy));
  36. }
  37. return new ChatBan
  38. {
  39. MemberID = memberID,
  40. RoomKey = string.IsNullOrWhiteSpace(roomKey) ? null : roomKey.Trim(),
  41. Reason = reason.Trim(),
  42. ExpiresAt = expiresAt,
  43. CreatedBy = createdBy.Trim()
  44. };
  45. }
  46. /// <summary>현재 시각 기준 유효한 제재인지</summary>
  47. public bool IsActiveAt(DateTime nowUtc) => ExpiresAt is null || ExpiresAt > nowUtc;
  48. /// <summary>제재 즉시 해제 — 만료 시각을 현재로 당김 (이력 보존)</summary>
  49. public void Lift(DateTime nowUtc)
  50. {
  51. if (!IsActiveAt(nowUtc))
  52. {
  53. return;
  54. }
  55. ExpiresAt = nowUtc;
  56. }
  57. }