using System.ComponentModel.DataAnnotations; namespace Domain.Entities.Chat; /// /// 채팅방 설정 (개미투자 D2) — RoomKey: main | stock:{code}. /// main 은 row 없이도 기본 오픈, 종목방은 row 존재 + IsActive 일 때만 오픈(상위 N 종목 단계 오픈 — d0 §5-④). /// public class ChatRoomConfig { /// 룸 키 (PK) — main, stock:005930 형식 [Key] public string RoomKey { get; private set; } = default!; /// 활성 여부 — 종목방 단계 오픈 게이트 public bool IsActive { get; private set; } = true; /// 슬로우 모드 (초) — 0 이면 전역 rate limit 만 적용 public short SlowModeSeconds { get; private set; } /// 상단 고정 공지 (선택) public string? Notice { get; private set; } public DateTime UpdatedAt { get; private set; } = DateTime.UtcNow; private ChatRoomConfig() { } public static ChatRoomConfig Create(string roomKey, bool isActive = true, short slowModeSeconds = 0, string? notice = null) { if (string.IsNullOrWhiteSpace(roomKey) || roomKey.Length > 20) { throw new ArgumentException("roomKey must be 1~20 chars", nameof(roomKey)); } if (slowModeSeconds < 0) { throw new ArgumentOutOfRangeException(nameof(slowModeSeconds)); } return new ChatRoomConfig { RoomKey = roomKey.Trim(), IsActive = isActive, SlowModeSeconds = slowModeSeconds, Notice = string.IsNullOrWhiteSpace(notice) ? null : notice.Trim() }; } public void Update(bool isActive, short slowModeSeconds, string? notice) { if (slowModeSeconds < 0) { throw new ArgumentOutOfRangeException(nameof(slowModeSeconds)); } IsActive = isActive; SlowModeSeconds = slowModeSeconds; Notice = string.IsNullOrWhiteSpace(notice) ? null : notice.Trim(); UpdatedAt = DateTime.UtcNow; } }