using System.ComponentModel.DataAnnotations; namespace Domain.Entities.Stocks; /// /// SEIBro 날짜 스윕 수집의 "조회 완료(0행 포함)" 마커 (자연키 UNIQUE (JobKey, Date, Discriminator)) — SEIBro 통합 리뷰 결함 #1 해소용. /// existsForDate 판정을 "그 날짜에 데이터 행이 있으면 수집됨"으로 하면, 발행/이벤트가 없는 조용한 날(주말 포함 전 캘린더일 스윕이라 특히 많음)이 /// 매 실행 재조회되어 quota 를 상시 낭비하고 백필이 수렴하지 않는다. 이 마커는 fetchAndUpsert 성공(0행 포함) 후 해당 (job, 날짜[, 축])을 /// 기록하고, 스윕의 스킵 판정을 "데이터 존재 OR 마커 존재"로 바꾼다(기존 적재분 재조회도 회피). /// Discriminator = 스윕 축 구분(tpcd·kacd·nation·pay구분 등). 축이 없는 스윕은 빈 문자열("")로 저장한다 — /// nullable 컬럼을 UNIQUE 에 넣으면 SQL Server 필터드 인덱스 처리가 애매해지므로 non-null 로 강제한다. /// public class SeibroSweptDate { [Key] public int ID { get; private set; } /// 수집 job 식별자 (예 "bond-issuance", "supply-lockup", "deriv-redemption") public string JobKey { get; private set; } = default!; /// 스윕 대상 날짜 (발행일·결제일·지급일 등 요청 파라미터 날짜) public DateOnly Date { get; private set; } /// 스윕 축 구분 (SECN_TPCD·SECN_KACD·NATION_CD·PAY_COST_TPCD 등). 축 없으면 빈 문자열. public string Discriminator { get; private set; } = string.Empty; /// 조회 완료 시각 (UTC) — 0행 응답도 완료로 기록 public DateTime SweptAt { get; private set; } = DateTime.UtcNow; private SeibroSweptDate() { } public static SeibroSweptDate Create(string jobKey, DateOnly date, string? discriminator) { if (string.IsNullOrWhiteSpace(jobKey)) { throw new ArgumentException("jobKey required", nameof(jobKey)); } return new SeibroSweptDate { JobKey = jobKey.Trim(), Date = date, Discriminator = string.IsNullOrWhiteSpace(discriminator) ? string.Empty : discriminator.Trim(), SweptAt = DateTime.UtcNow }; } }