111 lines
3.3 KiB
C#
111 lines
3.3 KiB
C#
using System.Text.Json;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace QuantEngine.Application.Services;
|
|
|
|
/// <summary>
|
|
/// Lightweight startup bootstrap for collection scheduling/readiness.
|
|
/// Writes a deterministic artifact so deployment can verify the collection
|
|
/// pipeline entry point without forcing a live collection run.
|
|
/// </summary>
|
|
public sealed class CollectionBootstrapHostedService : IHostedService
|
|
{
|
|
private readonly ILogger<CollectionBootstrapHostedService> _logger;
|
|
private readonly GatherTradingDataParser _parser;
|
|
|
|
public CollectionBootstrapHostedService(
|
|
ILogger<CollectionBootstrapHostedService> logger,
|
|
GatherTradingDataParser parser)
|
|
{
|
|
_logger = logger;
|
|
_parser = parser;
|
|
}
|
|
|
|
public Task StartAsync(CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
var repoRoot = FindRepoRoot();
|
|
var outputPath = Path.Combine(repoRoot, "Temp", "collection_bootstrap_v1.json");
|
|
var tickers = LoadBootstrapTickers();
|
|
|
|
Directory.CreateDirectory(Path.GetDirectoryName(outputPath)!);
|
|
File.WriteAllText(outputPath, JsonSerializer.Serialize(new
|
|
{
|
|
gate = "PASS",
|
|
generated_at_utc = DateTimeOffset.UtcNow,
|
|
bootstrap = "collection-scheduling-ready",
|
|
ticker_count = tickers.Count,
|
|
tickers
|
|
}, new JsonSerializerOptions { WriteIndented = true }));
|
|
|
|
_logger.LogInformation("Collection bootstrap artifact written to {Path}", outputPath);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "Collection bootstrap artifact generation failed");
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
|
|
|
private List<string> LoadBootstrapTickers()
|
|
{
|
|
try
|
|
{
|
|
var jsonPath = FindGatherTradingDataJson();
|
|
if (jsonPath is null)
|
|
{
|
|
return ["005930"];
|
|
}
|
|
|
|
var data = _parser.ParseGatherTradingData(jsonPath);
|
|
return data
|
|
.Select(row => row.TryGetValue("Ticker", out var value) ? value?.ToString()?.Trim('"') : null)
|
|
.Where(ticker => !string.IsNullOrWhiteSpace(ticker))
|
|
.Distinct()
|
|
.Take(10)
|
|
.ToList()!;
|
|
}
|
|
catch
|
|
{
|
|
return ["005930"];
|
|
}
|
|
}
|
|
|
|
private static string FindRepoRoot()
|
|
{
|
|
var current = new DirectoryInfo(AppContext.BaseDirectory);
|
|
while (current != null)
|
|
{
|
|
if (Directory.Exists(Path.Combine(current.FullName, ".git")))
|
|
{
|
|
return current.FullName;
|
|
}
|
|
current = current.Parent;
|
|
}
|
|
|
|
return Directory.GetCurrentDirectory();
|
|
}
|
|
|
|
private static string? FindGatherTradingDataJson()
|
|
{
|
|
var current = new DirectoryInfo(AppContext.BaseDirectory);
|
|
while (current != null)
|
|
{
|
|
var candidate = Path.Combine(current.FullName, "GatherTradingData.json");
|
|
if (File.Exists(candidate))
|
|
{
|
|
return candidate;
|
|
}
|
|
|
|
current = current.Parent;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|