refactor: Defer Phase 2-3 implementation to Task execution

Remove preliminary code files for OpenDart, KIS, RateLimiter services.
These will be implemented during Task #3-7 execution with proper:
- Error handling and type safety
- Database connection management
- Unit/integration tests
- AGENTS.md v16.0 compliance verification

Current state:
 Build: 0 errors, 0 warnings
 Tests: 116/116 PASS (verified clean state)
 DB Migration: 0031 ready (11 tables, 23 indexes)
 Documentation: Strategy + Checklist + Status ready

Next:
1. User starts Host (SSH tunnel + dotnet run)
2. Task #1: Gate 3 Shadow Run execution
3. Tasks #2-7: Phase 2-3 sequential implementation

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-08-02 17:57:25 +09:00
parent 494e7980a8
commit 31284927bc
4 changed files with 0 additions and 1009 deletions
@@ -1,111 +0,0 @@
using Hangfire;
using KArtSell.BuildingBlocks.Time;
using Serilog;
namespace KArtSell.Host.Jobs;
/// <summary>
/// OpenDart Daily Batch Job
/// Scheduled: 09:00 KST daily
/// Purpose: Fetch quarterly financial data for all tracked tickers
/// Idempotent: Safe to retry on same day (batch_date is unique key)
/// </summary>
[DisableConcurrentExecution(timeoutInSeconds: 3600)] // Max 1 hour
public sealed class OpenDartDailyBatchJob
{
private readonly Observability.OpenDartService _openDartService;
private readonly IClock _clock;
private readonly ILogger _logger;
public OpenDartDailyBatchJob(
Observability.OpenDartService openDartService,
IClock clock,
ILogger logger)
{
_openDartService = openDartService ?? throw new ArgumentNullException(nameof(openDartService));
_clock = clock ?? throw new ArgumentNullException(nameof(clock));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
/// <summary>
/// Execute daily OpenDart batch.
/// Idempotent: same batch_date always produces same result
/// </summary>
public async Task Execute(CancellationToken cancellationToken = default)
{
var jobId = CorrelationId.NewId();
var now = _clock.UtcNow;
_logger.Information(
"OpenDart daily batch started | JobId={JobId} | ScheduledFor={ScheduledFor}",
jobId, now);
try
{
await _openDartService.ExecuteDailyBatchAsync(cancellationToken);
_logger.Information(
"OpenDart daily batch completed successfully | JobId={JobId}",
jobId);
}
catch (OperationCanceledException)
{
_logger.Warning(
"OpenDart daily batch cancelled | JobId={JobId}",
jobId);
throw;
}
catch (InvalidOperationException ex) when (ex.Message.Contains("quota exceeded"))
{
_logger.Warning(
"OpenDart daily batch quota limit hit | JobId={JobId} | Error={Error}",
jobId, ex.Message);
throw;
}
catch (Exception ex)
{
_logger.Error(
ex,
"OpenDart daily batch failed | JobId={JobId}",
jobId);
throw;
}
}
}
/// <summary>
/// Extension to register OpenDart batch job with Hangfire
/// Schedule: 09:00 KST every day
/// </summary>
public static class OpenDartBatchJobExtensions
{
public static IServiceCollection AddOpenDartBatchJob(this IServiceCollection services)
{
// Registrations are handled in Program.cs
return services;
}
/// <summary>
/// Register recurring OpenDart batch job
/// Called from Program.cs during Host startup
/// </summary>
public static void RegisterOpenDartBatchJob(this IRecurringJobManager recurringJobManager)
{
recurringJobManager.AddOrUpdate<OpenDartDailyBatchJob>(
jobId: "opendart-daily-batch",
methodCall: job => job.Execute(default),
cronExpression: Cron.Daily(9, 0), // 09:00 every day (UTC)
options: new RecurringJobOptions
{
TimeZone = TimeZoneInfo.FindSystemTimeZoneById("Korea Standard Time") // 09:00 KST
});
}
}
/// <summary>
/// Helper for correlation tracking
/// </summary>
internal static class CorrelationId
{
public static Guid NewId() => Guid.NewGuid();
}