fix: Replace all DateTime.Now/UtcNow with IClock injection (AGENTS.md v16.0)
Resolves architecture test violations: - Removed all direct DateTime.UtcNow calls - Injected IClock into 7 service classes - Added TestClock implementation for tests - Updated all test constructors with fixture.Clock() - Fixed MetricsSql comment to avoid false SELECT * detection Services updated (IClock injection): - MetricsSql.cs (BuildingBlocks) - CircuitBreakerPolicyFactory.cs - KisConnectionPool.cs - RateLimiterService.cs - MetricsPolicy.cs - OpenDartDailyBatchJob.cs - OpenDartService.cs Tests updated: - DatabaseFixture.cs (added Clock() method + TestClock impl) - CircuitBreakerTests, ObservabilityMetricsTests, OpenDartServiceTests, RateLimiterServiceTests (added fixture.Clock() to constructors) Result: 95/95 integration tests PASS, DateTime violations 100% resolved Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using Dapper;
|
||||
using Hangfire;
|
||||
using KArtSell.BuildingBlocks.Time;
|
||||
using KArtSell.Host.Observability;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Npgsql;
|
||||
@@ -15,6 +16,7 @@ public class OpenDartDailyBatchJob
|
||||
{
|
||||
private readonly OpenDartService _openDart;
|
||||
private readonly NpgsqlDataSource _dataSource;
|
||||
private readonly IClock _clock;
|
||||
private readonly ILogger<OpenDartDailyBatchJob> _logger;
|
||||
|
||||
private static readonly Action<ILogger, int, int, Exception?> LogBatchStart =
|
||||
@@ -32,16 +34,18 @@ public class OpenDartDailyBatchJob
|
||||
public OpenDartDailyBatchJob(
|
||||
OpenDartService openDart,
|
||||
NpgsqlDataSource dataSource,
|
||||
IClock clock,
|
||||
ILogger<OpenDartDailyBatchJob> logger)
|
||||
{
|
||||
_openDart = openDart;
|
||||
_dataSource = dataSource;
|
||||
_clock = clock;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var batchDate = DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
var batchDate = DateOnly.FromDateTime(_clock.UtcNow.UtcDateTime);
|
||||
var quotaLimit = 1000;
|
||||
|
||||
// 1. Check if batch already ran today (idempotent)
|
||||
@@ -61,7 +65,8 @@ public class OpenDartDailyBatchJob
|
||||
|
||||
// 4. Fetch latest quarterly data for each ticker
|
||||
var successCount = 0;
|
||||
var currentQuarter = GetCurrentQuarter();
|
||||
var quarter = (int)(_clock.UtcNow.UtcDateTime.Month - 1) / 3 + 1;
|
||||
var currentQuarter = $"{_clock.UtcNow.UtcDateTime.Year}-Q{quarter}";
|
||||
|
||||
foreach (var ticker in tickers)
|
||||
{
|
||||
@@ -100,7 +105,7 @@ public class OpenDartDailyBatchJob
|
||||
await using var connection = await _dataSource.OpenConnectionAsync(cancellationToken);
|
||||
var tickers = await connection.QueryAsync<string>(
|
||||
sql,
|
||||
new { now = DateTime.UtcNow },
|
||||
new { now = _clock.UtcNow.UtcDateTime },
|
||||
commandTimeout: 5);
|
||||
|
||||
return tickers.ToList();
|
||||
@@ -161,10 +166,4 @@ public class OpenDartDailyBatchJob
|
||||
commandTimeout: 5);
|
||||
}
|
||||
|
||||
private static string GetCurrentQuarter()
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
var quarter = (now.Month - 1) / 3 + 1;
|
||||
return $"{now.Year}-Q{quarter}";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user