using Application.Abstractions.Data;
using Application.Abstractions.Messaging;
using Microsoft.EntityFrameworkCore;
namespace Application.Features.Api.Stocks.Watch.IsWatching;
/// 회원이 관심 등록한 코드 집합을 조회해 요청 코드별 true/false 맵을 반환 (IsFollowing 패턴).
internal sealed class Handler(IAppDbContext db) : IQueryHandler
{
// 방어적 상한 — 엔드포인트에서도 Take(100) 하지만 Handler 계층 자체도 무방비가 되지 않도록 (GetQuotes 패턴)
public const int MaxCodes = 100;
public async Task Handle(Query request, CancellationToken ct)
{
var codes = request.Codes.Select(c => c.Trim()).Where(c => c.Length > 0).Distinct().Take(MaxCodes).ToArray();
if (codes.Length == 0)
{
return new Response { Map = new Dictionary() };
}
var watched = await db.StockWatch.AsNoTracking()
.Where(w => w.MemberID == request.MemberID && codes.Contains(w.StockCode))
.Select(w => w.StockCode)
.ToListAsync(ct);
var watchedSet = watched.ToHashSet();
var map = codes.ToDictionary(c => c, c => watchedSet.Contains(c));
return new Response { Map = map };
}
}