| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 |
- using Application.Abstractions.Cache;
- using Application.Abstractions.Chat;
- using Application.Abstractions.Data;
- using Microsoft.EntityFrameworkCore;
- namespace Application.Helpers;
- /// <summary>
- /// ChatRoomConfig 로더 — Redis 캐시(60초 TTL) → MSSQL 폴백.
- /// 오픈 판정: main 은 row 없어도 기본 오픈, 종목방은 row 존재 + IsActive 필요(단계 오픈 — d0 §5-④),
- /// 레거시 channel:{sid} 룸은 항상 통과(기존 채널 채팅 동작 유지).
- /// </summary>
- public static class ChatRoomConfigLoader
- {
- public sealed record RoomConfig(bool Exists, bool IsActive, short SlowModeSeconds, string? Notice);
- private static readonly TimeSpan CacheTtl = TimeSpan.FromSeconds(60);
- public static async Task<RoomConfig> GetAsync(ICacheService cache, IAppDbContext db, string roomKey, CancellationToken ct)
- {
- var cacheKey = CacheKeys.ChatRoomConfig(roomKey);
- var cached = await cache.GetAsync<RoomConfig>(cacheKey);
- if (cached is not null)
- {
- return cached;
- }
- var row = await db.ChatRoomConfig.AsNoTracking().Where(c => c.RoomKey == roomKey).Select(c => new { c.IsActive, c.SlowModeSeconds, c.Notice }).FirstOrDefaultAsync(ct);
- var config = row is null
- ? new RoomConfig(false, false, 0, null)
- : new RoomConfig(true, row.IsActive, row.SlowModeSeconds, row.Notice);
- await cache.SetAsync(cacheKey, config, CacheTtl);
- return config;
- }
- public static bool IsRoomOpen(string roomKey, RoomConfig config)
- {
- if (roomKey == ChatRoomKeys.Main)
- {
- return !config.Exists || config.IsActive;
- }
- if (ChatRoomKeys.IsStockRoom(roomKey))
- {
- return config.Exists && config.IsActive;
- }
- return true;
- }
- }
|